refactor: Refactorized whole project structure

This commit is contained in:
AURUMVORXX
2025-01-24 22:36:25 +03:00
parent d50f55086b
commit a479b5f85d
321 changed files with 288 additions and 219 deletions

View File

@@ -0,0 +1,14 @@
target_sources(${PYG2O_MODULE_NAME}
PRIVATE
source/Array.cpp
source/Class.cpp
source/Constant.cpp
source/CustomTypes.cpp
source/StaticClass.cpp
)
target_include_directories(${PYG2O_MODULE_NAME}
PRIVATE
"include/"
)

21
source/NoNut/LICENSE Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) Martis
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

2
source/NoNut/README.md Normal file
View File

@@ -0,0 +1,2 @@
Modified version of a C++ wrapper for the Gothic 2 Online API
Original: https://gitlab.com/g2o/modules/dependencies/nonut

View File

@@ -0,0 +1,51 @@
#ifndef NONUT_CORE_ARRAY_H
#define NONUT_CORE_ARRAY_H
#include "CommonHeader.h"
#include "Utils.h"
#include <sqapi.h>
namespace nonut
{
class Array
{
public:
explicit Array(SQObject object);
~Array();
[[nodiscard]] size_t size() const;
template <typename T>
T get(const String index)
{
HSQUIRRELVM vm = Sqrat::DefaultVM::Get();
T result{};
sq_pushobject(vm, object);
sq_pushstring(vm, index.c_str(), index.length());
if (SQ_FAILED(sq_get(vm, -2)))
{
sq_pop(vm, 1);
return result;
}
if constexpr (std::is_same_v<T, String>)
{
const SQChar* intermediateResult = nullptr;
sq_getstring(vm, -1, &intermediateResult);
result = intermediateResult;
}
else
{
sqGetValue(vm, -1, &result);
}
sq_pop(vm, 2);
return result;
}
private:
SQObject object;
size_t cachedSize;
};
}
#endif // NONUT_CORE_ARRAY_H

View File

@@ -0,0 +1,32 @@
#ifndef NONUT_CORE_BIND_H
#define NONUT_CORE_BIND_H
#include "CommonHeader.h"
#include <vector>
namespace nonut
{
//TODO: Finish Bind and remove placeholder
class Bind
{
public:
static void registerFunction(String funcName, const SQFUNCTION func, size_t funcSize)
{
HSQUIRRELVM vm = Sqrat::DefaultVM::Get();
const auto top = sq_gettop(vm);
sq_pushroottable(vm);
sq_pushstring(vm, funcName.c_str(), funcName.length());
sq_newclosure(vm, func, 0); //create a new function
sq_newslot(vm, -3, SQFalse);
sq_settop(vm, top);
}
//template<typename F>
//static void Function(String functionName, F& function)
//{
//
//}
};
}
#endif // NONUT_CORE_BIND_H

View File

@@ -0,0 +1,45 @@
#ifndef NONUT_CORE_CLASS_H
#define NONUT_CORE_CLASS_H
#include "CommonHeader.h"
#include <string>
#include "Function.h"
// ReSharper disable once CppUnusedIncludeDirective
#include "Property.h"
#include "Instance.h"
#define METHOD_CTOR(methodName) methodName(#methodName, this->classObjectInstance, this->classObject)
#define PROPERTY_CTOR(propertyName) propertyName(#propertyName, this->classObjectInstance)
#define COPY_CTOR(type) type(const type& other) : type(other.getInstance()){} \
type& operator=(const type& other) = delete
namespace nonut
{
static constexpr auto CONSTRUCTOR_NAME = "constructor";
class Class : public Instance
{
public:
Class(const String& className, SQObject classObjectInstance = SQ_NULL);
virtual ~Class();
[[nodiscard]] SQObject getInstance() const override;
bool isNull() const;
protected:
// Object holding information about class
SQObject classObject{};
// Class object instance
SQObject classObjectInstance{};
template <typename... Args>
void classCtor(Args ... args)
{
Function<void, Args...> ctor(CONSTRUCTOR_NAME, classObjectInstance, classObject);
ctor(std::forward<Args>(args)...);
}
bool bIsNull = false;
};
}
#endif // NONUT_CORE_CLASS_H

View File

@@ -0,0 +1,18 @@
#ifndef CORE_COMMONHEADER_H_
#define CORE_COMMONHEADER_H_
#include "sqrat.h"
namespace nonut
{
using Int = SQInteger;
using UInt = SQUnsignedInteger;
using UInt32 = SQUnsignedInteger32;
using Float = SQFloat;
using Bool = SQBool;
using String = std::string;
constexpr SQObject SQ_NULL{ OT_NULL };
}
#endif // CORE_COMMONHEADER_H_

View File

@@ -0,0 +1,10 @@
#ifndef NONUT_CORE_CONSTANT_H
#define NONUT_CORE_CONSTANT_H
#include "CommonHeader.h"
#include <sqapi.h>
namespace nonut
{
SQObject getConstTable();
};
#endif // NONUT_CORE_CONSTANT_H

View File

@@ -0,0 +1,182 @@
#ifndef NONUT_G2O_SHARED_CUSTOM_TYPES_H
#define NONUT_G2O_SHARED_CUSTOM_TYPES_H
#include <string>
#include <pybind11/embed.h>
#include "Utils.h"
namespace py = pybind11;
namespace nonut
{
struct GameTime : CustomType
{
void convert(SQObject object) override;
Int day{};
Int hour{};
Int min{};
auto toTuple()
{
return std::make_tuple(day, hour, min);
}
};
struct Position2d : CustomType
{
void convert(SQObject object) override;
Int x{};
Int y{};
auto toTuple()
{
return std::make_tuple(x, y);
}
};
struct Position3d : CustomType
{
void convert(SQObject object) override;
Float x{};
Float y{};
Float z{};
auto toTuple()
{
return std::make_tuple(x, y, z);
}
};
struct Size2d : CustomType
{
void convert(SQObject object) override;
Int width{};
Int height{};
auto toTuple()
{
return std::make_tuple(width, height);
}
};
struct Rect : CustomType
{
void convert(SQObject object) override;
Int x;
Int y;
Int width;
Int height;
auto toTuple()
{
return std::make_tuple(x, y, width, height);
}
};
struct UV : CustomType
{
void convert(SQObject object) override;
Float x;
Float y;
Float width;
Float height;
auto toTuple()
{
return std::make_tuple(x, y, width, height);
}
};
struct Resolution : CustomType
{
void convert(SQObject object) override;
Int x{};
Int y{};
Int bpp{};
auto toTuple()
{
return std::make_tuple(x, y, bpp);
}
};
struct Item : CustomType
{
void convert(SQObject object) override;
Int instance{};
Int amount{};
String name{};
auto toTuple()
{
return std::make_tuple(instance, amount, name);
}
};
struct Color : CustomType
{
void convert(SQObject object) override;
Int r{};
Int g{};
Int b{};
auto toTuple()
{
return std::make_tuple(r, g, b);
}
};
struct BodyVisual : CustomType
{
void convert(SQObject object) override;
String bodyModel{};
Int bodyTxt{};
String headModel{};
Int headTxt{};
auto toTuple()
{
return std::make_tuple(bodyModel, bodyTxt, headModel, headTxt);
}
};
struct NetworkStats : CustomType
{
void convert(SQObject object) override;
Int packetReceived{};
Int packetlossTotal{};
Int packetlossLastSecond{};
Int messagesInResendBuffer{};
Int messageInSendBuffer{};
Int bytesInResendBuffer{};
Int bytesInSendBuffer{};
auto toTuple()
{
return std::make_tuple(
packetReceived,
packetlossTotal,
packetlossLastSecond,
messagesInResendBuffer,
messageInSendBuffer,
bytesInResendBuffer,
bytesInSendBuffer);
}
};
struct Position3dWithName : CustomType
{
void convert(SQObject object) override;
String name{};
Float x{};
Float y{};
Float z{};
auto toTuple()
{
return std::make_tuple(name, x, y, z);
}
};
struct SqDict : CustomType
{
void convert(SQObject object) override;
py::dict data{};
};
struct SqList : CustomType
{
void convert(SQObject object) override;
py::list data{};
};
}
#endif // NONUT_G2O_SHARED_CUSTOM_TYPES_H

View File

@@ -0,0 +1,166 @@
#ifndef NONUT_CORE_FUNCTION_H
#define NONUT_CORE_FUNCTION_H
#include <optional>
#include <string>
#include <sqapi.h>
#include "Utils.h"
#define FUNCTION_CTOR(function) function(#function)
namespace nonut
{
class Class;
template <typename ReturnType, typename... Args>
class Function
{
public:
// Ctor for functions
Function(const String& functionName, const SQObject env = getRootTable()) : envObj(env)
{
HSQUIRRELVM vm = Sqrat::DefaultVM::Get();
sq_pushobject(vm, envObj);
sq_pushstring(vm, functionName.c_str(), functionName.length());
// get the function from the root table
if (SQ_FAILED(sq_get(vm, -2)))
{
sq_pop(vm, 1);
throw;
}
// check the type
if (const SQObjectType value_type = sq_gettype(vm, -1); value_type != OT_CLOSURE && value_type !=
OT_NATIVECLOSURE)
{
sq_pop(vm, 2);
throw;
}
// get function and add ref
sq_getstackobj(vm, -1, &funcObj);
sq_addref(vm, &funcObj);
sq_pop(vm, 2);
}
// Ctor for class methods
Function(const String& functionName, const SQObject classObjectInstance,
const SQObject classObject) : envObj(classObjectInstance)
{
HSQUIRRELVM vm = Sqrat::DefaultVM::Get();
isClassMethod = true; // Prevent release of the resources cause we don't own them
sq_pushobject(vm, classObject);
sq_pushstring(vm, functionName.c_str(), functionName.length());
// get the function from the root table
if (SQ_FAILED(sq_get(vm, -2)))
{
sq_pop(vm, 1);
throw;
}
// check the type
if (const SQObjectType value_type = sq_gettype(vm, -1); value_type != OT_CLOSURE && value_type !=
OT_NATIVECLOSURE)
{
sq_pop(vm, 2);
throw;
}
// get function and add ref
sq_getstackobj(vm, -1, &funcObj);
sq_addref(vm, &funcObj);
sq_pop(vm, 2);
}
~Function()
{
if (!isClassMethod)
{
HSQUIRRELVM vm = Sqrat::DefaultVM::Get();
sq_release(vm, &funcObj);
sq_release(vm, &envObj);
sq_resetobject(&funcObj);
sq_resetobject(&envObj);
}
}
ReturnType operator()(Args ... args)
{
HSQUIRRELVM vm = Sqrat::DefaultVM::Get();
const auto top = sq_gettop(vm);
sq_pushobject(vm, funcObj);
sq_pushobject(vm, envObj);
auto debug = sq_gettop(vm);
(sqPushValue(vm, args), ...);
if constexpr (std::is_same_v<ReturnType, void>)
{
debug = sq_gettop(vm);
auto returnCode = sq_call(vm, ARG_COUNT + 1, SQFalse, SQFalse); // TODO: HANDLE ERROR RETURN CODE
sq_pop(vm, 2);
sq_settop(vm, top);
return void();
}
else
{
auto returnCode = sq_call(vm, ARG_COUNT + 1, SQTrue, SQFalse); // TODO: HANDLE ERROR RETURN CODE
std::optional<ReturnType> result;
if constexpr (std::derived_from<ReturnType, CustomType>)
{
result = std::make_optional<ReturnType>();
auto intermediateResult = returnVar<SQObject>();
result.value().convert(intermediateResult);
sq_release(vm, &intermediateResult);
sq_resetobject(&intermediateResult);
}
else if constexpr (std::derived_from<ReturnType, Class>)
{
auto intermediateResult = returnVar<SQObject>();
//result = std::make_optional<ReturnType>(ReturnType(intermediateResult));
result.emplace(ReturnType(intermediateResult));
sq_release(vm, &intermediateResult);
sq_resetobject(&intermediateResult);
}
else
{
result = std::make_optional<ReturnType>(returnVar<ReturnType>());
}
sq_pop(vm, 2);
sq_settop(vm, top);
return result.value();
}
}
[[nodiscard]] SQObject getObject() const
{
return funcObj;
}
private:
SQObject funcObj{};
SQObject envObj{};
bool isClassMethod = false;
static constexpr auto ARG_COUNT{sizeof...(Args)};
static SQObject getRootTable()
{
HSQUIRRELVM vm = Sqrat::DefaultVM::Get();
SQObject rootTable{};
sq_pushroottable(vm);
sq_getstackobj(vm, -1, &rootTable);
sq_addref(vm, &rootTable);
sq_pop(vm, 1); // pop root table
return rootTable;
}
};
}
#endif // NONUT_CORE_FUNCTION_H

View File

@@ -0,0 +1,13 @@
#ifndef NONUT_CORE_INSTANCE_H
#define NONUT_CORE_INSTANCE_H
#include <sqapi.h>
namespace nonut
{
class Instance
{
public:
[[nodiscard]] virtual SQObject getInstance() const = 0;
};
}
#endif //NONUT_CORE_INSTANCE_H

View File

@@ -0,0 +1,135 @@
#ifndef NONUT_CORE_PROPERTY_H
#define NONUT_CORE_PROPERTY_H
#include <string>
#include <sqapi.h>
#include "Utils.h"
#include "Class.h"
namespace nonut
{
template <typename T>
T getProperty(const SQObject& object, const String& name)
{
HSQUIRRELVM vm = Sqrat::DefaultVM::Get();
const auto top = sq_gettop(vm);
sq_pushobject(vm, object);
sq_pushstring(vm, name.c_str(), name.length());
if constexpr (std::derived_from<T, Class>)
{
SQObject intermediateResult{};
if (SQ_SUCCEEDED(sq_get(vm, -2))) // pops property
{
sqGetValue(vm, -1, &intermediateResult);
sq_pop(vm, 1); // pops result
}
sq_pop(vm, 1); // pops object
sq_settop(vm, top);
return T(intermediateResult);
}
else
{
T result{};
if (SQ_SUCCEEDED(sq_get(vm, -2))) // pops property
{
sqGetValue(vm, -1, &result);
sq_pop(vm, 1); // pops result
}
sq_pop(vm, 1); // pops object
sq_settop(vm, top);
return result;
}
}
template <>
inline bool getProperty<bool>(const SQObject& object, const String& name)
{
return getProperty<Bool>(object, name);
}
template <>
inline String getProperty<String>(const SQObject& object, const String& name)
{
HSQUIRRELVM vm = Sqrat::DefaultVM::Get();
const Int top = sq_gettop(vm);
const SQChar* result{};
sq_pushobject(vm, object);
sq_pushstring(vm, name.c_str(), name.length());
if (SQ_SUCCEEDED(sq_get(vm, -2))) // pops property
{
sq_getstring(vm, -1, &result);
sq_pop(vm, 1); // pops result
}
sq_pop(vm, 1); // pops object
sq_settop(vm, top);
return result;
}
template <typename T>
void setProperty(SQObject& object, String& name, T value)
{
HSQUIRRELVM vm = Sqrat::DefaultVM::Get();
sq_pushobject(vm, object);
sq_pushstring(vm, name.c_str(), name.length());
if constexpr (std::derived_from<T, Class>)
{
sqPushValue(vm, value.getInstance());
}
else
{
sqPushValue(vm, value);
}
auto result = sq_set(vm, -3); // pops name and value
sq_pop(vm, 1); // pops object
}
template <typename T, bool IsReadOnly = false>
class Property
{
public:
Property(String propertyName, const SQObject object) : object(object),
propertyName(std::move(propertyName))
{
}
Property<T>& operator=(const T& other) noexcept
{
set(other);
return *this;
}
operator T()
{
return this->get();
}
[[nodiscard]] T get() const
{
return getProperty<T>(object, propertyName);
}
void set(T value)
{
static_assert(!IsReadOnly, "Cannot set read-only property.");
setProperty<T>(object, propertyName, value);
}
private:
SQObject object;
String propertyName;
};
}
#endif // NONUT_CORE_PROPERTY_H

View File

@@ -0,0 +1,25 @@
#ifndef NONUT_CORE_STATIC_CLASS_H
#define NONUT_CORE_STATIC_CLASS_H
#include "Function.h"
#include "Property.h"
#define METHOD_CTOR(methodName) methodName(#methodName, this->classObjectInstance, this->classObject)
#define PROPERTY_CTOR(propertyName) propertyName(#propertyName, this->classObjectInstance)
namespace nonut
{
class StaticClass
{
public:
explicit StaticClass(const String& className);
~StaticClass();
protected:
// Object holding information about class
SQObject classObject{};
// Class object instance
SQObject classObjectInstance{};
};
}
#endif // NONUT_CORE_STATIC_CLASS_H

View File

@@ -0,0 +1,347 @@
#ifndef NONUT_CORE_STRING_HELPERS_H
#define NONUT_CORE_STRING_HELPERS_H
#include <string>
#include <unordered_map>
namespace nonut
{
const std::unordered_map<unsigned char, std::string_view> WINDOWS1250_UTF8_MAP
{
{'\x80', "\xe2\x82\xac"}, // euro sign
{'\x82', "\xe2\x80\x9a"}, // lower quotation mark
{'\x84', "\xe2\x80\x9e"}, // lower quotation marks
{'\x85', "\xe2\x80\xa6"}, // ellipsis
{'\x86', "\xe2\x80\xa0"}, // dagger
{'\x87', "\xe2\x80\xa1"}, // double dagger
{'\x89', "\xe2\x80\xb0"}, // per mille
{'\x8a', "\xc5\xa0"}, // S with caron
{'\x8b', "\xe2\x80\xb9"}, // left guillemet
{'\x8c', "\xc5\x9a"}, // S with acute
{'\x8d', "\xc5\xa4"}, // T with caron
{'\x8e', "\xc5\xbd"}, // Z with caron
{'\x8f', "\xc5\xb9"}, // Z with acute
{'\x91', "\xe2\x80\x98"}, // upper quotation mark (opening)
{'\x92', "\xe2\x80\x99"}, // upper quotation mark (closing)
{'\x93', "\xe2\x80\x9c"}, // upper quotation marks (opening)
{'\x94', "\xe2\x80\x9d"}, // upper quotation marks (closing)
{'\x95', "\xe2\x80\xa2"}, // bullet sign
{'\x96', "\xe2\x80\x93"}, // en dash
{'\x97', "\xe2\x80\x94"}, // em dash
{'\x99', "\xe2\x84\xa2"}, // trademark sign
{'\x9a', "\xc5\xa1"}, // s with caron
{'\x9b', "\xe2\x80\xba"}, // right guillemet
{'\x9c', "\xc5\x9b"}, // s with acute
{'\x9d', "\xc5\xa5"}, // t with caron
{'\x9e', "\xc5\xbe"}, // z with caron
{'\x9f', "\xc5\xba"}, // z with acute
{'\xa0', "\x20"}, // NBSP
{'\xa1', "\xcb\x87"}, // caron
{'\xa2', "\xcb\x98"}, // breve
{'\xa3', "\xc5\x81"}, // L with stroke
{'\xa4', "\xc2\xa4"}, // currency sign
{'\xa5', "\xc4\x84"}, // A with ogonek
{'\xa6', "\xc2\xa6"}, // vertical bar
{'\xa7', "\xc2\xa7"}, // section sign
{'\xa8', "\xc2\xa8"}, // diaeresis
{'\xa9', "\xc2\xa9"}, // copyright sign
{'\xaa', "\xc5\x9e"}, // S-cedilla
{'\xab', "\xc2\xab"}, // left guillemets
{'\xac', "\xc2\xac"}, // negation
{'\xad', "\xc2\xad"}, // soft hyphen
{'\xae', "\xc2\xae"}, // registered trademark sign
{'\xaf', "\xc5\xbb"}, // Z with dot above
{'\xb0', "\xc2\xb0"}, // degree sign
{'\xb1', "\xc2\xb1"}, // plus-minus sign
{'\xb2', "\xcb\x9b"}, // ogonek
{'\xb3', "\xc5\x82"}, // l with stroke
{'\xb4', "\xc2\xb4"}, // acute accent
{'\xb5', "\xc2\xb5"}, // Mu letter
{'\xb6', "\xc2\xb6"}, // pilcrow
{'\xb7', "\xc2\xb7"}, // middle dot
{'\xb8', "\xc2\xb8"}, // cedilla
{'\xb9', "\xc4\x85"}, // a with ogonek
{'\xba', "\xc5\x9f"}, // s-cedilla
{'\xbb', "\xc2\xbb"}, // right guillemets
{'\xbc', "\xc4\xbd"}, // Lj-
{'\xbd', "\xcb\x9d"}, // double acute accent
{'\xbe', "\xc4\xbe"}, // lj-
{'\xbf', "\xc5\xbc"}, // z with dot above
{'\xc0', "\xc5\x94"}, // R with acute
{'\xc1', "\xc3\x81"}, // A with acute
{'\xc2', "\xc3\x82"}, // A-circumflex
{'\xc3', "\xc4\x82"}, // A-breve
{'\xc4', "\xc3\x84"}, // A with diaeresis
{'\xc5', "\xc4\xb9"}, // L with acute
{'\xc6', "\xc4\x86"}, // C with acute
{'\xc7', "\xc3\x87"}, // C-cedilla
{'\xc8', "\xc4\x8c"}, // C with caron
{'\xc9', "\xc3\x89"}, // C with acute
{'\xca', "\xc4\x98"}, // E with ogonek
{'\xcb', "\xc3\x8b"}, // E with diaeresis
{'\xcc', "\xc3\x8b"}, // E with caron
{'\xcd', "\xc3\x8d"}, // I with acute
{'\xce', "\xc3\x8e"}, // I-circumflex
{'\xcf', "\xc4\x8e"}, // D with caron
{'\xd0', "\xc4\x90"}, // crossed D
{'\xd1', "\xc5\x83"}, // N with acute
{'\xd2', "\xc5\x87"}, // N with caron
{'\xd3', "\xc3\x93"}, // O with acute
{'\xd4', "\xc3\x94"}, // O-circumflex
{'\xd5', "\xc5\x90"}, // O with dobule accute
{'\xd6', "\xc3\x96"}, // O with diaeresis
{'\xd7', "\xc3\x97"}, // multiplication sign
{'\xd8', "\xc5\x98"}, // R with caron
{'\xd9', "\xc5\xae"}, // U with diacritic
{'\xda', "\xc3\x9a"}, // U with acute
{'\xdb', "\xc5\xb0"}, // U with double accent
{'\xdc', "\xc3\x9c"}, // U with diaeresis
{'\xdd', "\xc3\x9d"}, // Y with acute
{'\xdf', "\xc5\xa2"}, // T-cedilla
{'\xe0', "\xc5\x95"}, // r with acute
{'\xe1', "\xc3\xa1"}, // a with acute
{'\xe2', "\xc3\xa2"}, // a-circumflex
{'\xe3', "\xc4\x83"}, // a-breve
{'\xe4', "\xc3\xa4"}, // a with diaeresis
{'\xe5', "\xc4\xba"}, // l with acute
{'\xe6', "\xc4\x87"}, // c with acute
{'\xe7', "\xc3\xa7"}, // c-cedilla
{'\xe8', "\xc4\x8d"}, // c with caron
{'\xe9', "\xc3\xa9"}, // c with acute
{'\xea', "\xc4\x99"}, // e with ogonek
{'\xeb', "\xc3\xab"}, // e with diaeresis
{'\xec', "\xc4\x9b"}, // e with caron
{'\xed', "\xc3\xad"}, // i with acute
{'\xee', "\xc3\xae"}, // i-circumflex
{'\xef', "\xc4\x8f"}, // d with caron
{'\xf0', "\xc4\x91"}, // crossed d
{'\xf1', "\xc5\x84"}, // n with acute
{'\xf2', "\xc5\x88"}, // n with caron
{'\xf3', "\xc3\xb3"}, // o with acute
{'\xf4', "\xc3\xb4"}, // o-circumflex
{'\xf5', "\xc5\x91"}, // o with double accent
{'\xf6', "\xc3\xb6"}, // o with diaeresis
{'\xf7', "\xc3\xb7"}, // division sign
{'\xf8', "\xc5\x99"}, // r with caron
{'\xf9', "\xc5\xaf"}, // u with diacritic
{'\xfa', "\xc3\xba"}, // u with acute
{'\xfb', "\xc5\xb1"}, // u with double accent
{'\xfc', "\xc3\xbc"}, // u with diaeresis
{'\xfd', "\xc3\xbd"}, // y with acute
{'\xfe', "\xc5\xa3"}, // t-cedilla
{'\xff', "\xcb\x99"}, // diactric dot
};
const std::unordered_map<std::string_view, unsigned char> UTF8_WINDOWS1250_MAP
{
{"\xe2\x82\xac", '\x80'}, // euro sign
{"\xe2\x80\x9a", '\x82'}, // lower quotation mark
{"\xe2\x80\x9e", '\x84'}, // lower quotation marks
{"\xe2\x80\xa6", '\x85'}, // ellipsis
{"\xe2\x80\xa0", '\x86'}, // dagger
{"\xe2\x80\xa1", '\x87'}, // double dagger
{"\xe2\x80\xb0", '\x89'}, // per mille
{"\xc5\xa0", '\x8a'}, // S with caron
{"\xe2\x80\xb9", '\x8b'}, // left guillemet
{"\xc5\x9a", '\x8c'}, // S with acute
{"\xc5\xa4", '\x8d'}, // T with caron
{"\xc5\xbd", '\x8e'}, // Z with caron
{"\xc5\xb9", '\x8f'}, // Z with acute
{"\xe2\x80\x98", '\x91'}, // upper quotation mark (opening)
{"\xe2\x80\x99", '\x92'}, // upper quotation mark (closing)
{"\xe2\x80\x9c", '\x93'}, // upper quotation marks (opening)
{"\xe2\x80\x9d", '\x94'}, // upper quotation marks (closing)
{"\xe2\x80\xa2", '\x95'}, // bullet sign
{"\xe2\x80\x93", '\x96'}, // en dash
{"\xe2\x80\x94", '\x97'}, // em dash
{"\xe2\x84\xa2", '\x99'}, // trademark sign
{"\xc5\xa1", '\x9a'}, // s with caron
{"\xe2\x80\xba", '\x9b'}, // right guillemet
{"\xc5\x9b", '\x9c'}, // s with acute
{"\xc5\xa5", '\x9d'}, // t with caron
{"\xc5\xbe", '\x9e'}, // z with caron
{"\xc5\xba", '\x9f'}, // z with acute
{"\x20", '\xa0'}, // NBSP
{"\xcb\x87", '\xa1'}, // caron
{"\xcb\x98", '\xa2'}, // breve
{"\xc5\x81", '\xa3'}, // L with stroke
{"\xc2\xa4", '\xa4'}, // currency sign
{"\xc4\x84", '\xa5'}, // A with ogonek
{"\xc2\xa6", '\xa6'}, // vertical bar
{"\xc2\xa7", '\xa7'}, // section sign
{"\xc2\xa8", '\xa8'}, // diaeresis
{"\xc2\xa9", '\xa9'}, // copyright sign
{"\xc5\x9e", '\xaa'}, // S-cedilla
{"\xc2\xab", '\xab'}, // left guillemets
{"\xc2\xac", '\xac'}, // negation
{"\xc2\xad", '\xad'}, // soft hyphen
{"\xc2\xae", '\xae'}, // registered trademark sign
{"\xc5\xbb", '\xaf'}, // Z with dot above
{"\xc2\xb0", '\xb0'}, // degree sign
{"\xc2\xb1", '\xb1'}, // plus-minus sign
{"\xcb\x9b", '\xb2'}, // ogonek
{"\xc5\x82", '\xb3'}, // l with stroke
{"\xc2\xb4", '\xb4'}, // acute accent
{"\xc2\xb5", '\xb5'}, // Mu letter
{"\xc2\xb6", '\xb6'}, // pilcrow
{"\xc2\xb7", '\xb7'}, // middle dot
{"\xc2\xb8", '\xb8'}, // cedilla
{"\xc4\x85", '\xb9'}, // a with ogonek
{"\xc5\x9f", '\xba'}, // s-cedilla
{"\xc2\xbb", '\xbb'}, // right guillemets
{"\xc4\xbd", '\xbc'}, // Lj-
{"\xcb\x9d", '\xbd'}, // double acute accent
{"\xc4\xbe", '\xbe'}, // lj-
{"\xc5\xbc", '\xbf'}, // z with dot above
{"\xc5\x94", '\xc0'}, // R with acute
{"\xc3\x81", '\xc1'}, // A with acute
{"\xc3\x82", '\xc2'}, // A-circumflex
{"\xc4\x82", '\xc3'}, // A-breve
{"\xc3\x84", '\xc4'}, // A with diaeresis
{"\xc4\xb9", '\xc5'}, // L with acute
{"\xc4\x86", '\xc6'}, // C with acute
{"\xc3\x87", '\xc7'}, // C-cedilla
{"\xc4\x8c", '\xc8'}, // C with caron
{"\xc3\x89", '\xc9'}, // C with acute
{"\xc4\x98", '\xca'}, // E with ogonek
{"\xc3\x8b", '\xcb'}, // E with diaeresis
{"\xc3\x8b", '\xcc'}, // E with caron
{"\xc3\x8d", '\xcd'}, // I with acute
{"\xc3\x8e", '\xce'}, // I-circumflex
{"\xc4\x8e", '\xcf'}, // D with caron
{"\xc4\x90", '\xd0'}, // crossed D
{"\xc5\x83", '\xd1'}, // N with acute
{"\xc5\x87", '\xd2'}, // N with caron
{"\xc3\x93", '\xd3'}, // O with acute
{"\xc3\x94", '\xd4'}, // O-circumflex
{"\xc5\x90", '\xd5'}, // O with dobule accute
{"\xc3\x96", '\xd6'}, // O with diaeresis
{"\xc3\x97", '\xd7'}, // multiplication sign
{"\xc5\x98", '\xd8'}, // R with caron
{"\xc5\xae", '\xd9'}, // U with diacritic
{"\xc3\x9a", '\xda'}, // U with acute
{"\xc5\xb0", '\xdb'}, // U with double accent
{"\xc3\x9c", '\xdc'}, // U with diaeresis
{"\xc3\x9d", '\xdd'}, // Y with acute
{"\xc5\xa2", '\xdf'}, // T-cedilla
{"\xc5\x95", '\xe0'}, // r with acute
{"\xc3\xa1", '\xe1'}, // a with acute
{"\xc3\xa2", '\xe2'}, // a-circumflex
{"\xc4\x83", '\xe3'}, // a-breve
{"\xc3\xa4", '\xe4'}, // a with diaeresis
{"\xc4\xba", '\xe5'}, // l with acute
{"\xc4\x87", '\xe6'}, // c with acute
{"\xc3\xa7", '\xe7'}, // c-cedilla
{"\xc4\x8d", '\xe8'}, // c with caron
{"\xc3\xa9", '\xe9'}, // c with acute
{"\xc4\x99", '\xea'}, // e with ogonek
{"\xc3\xab", '\xeb'}, // e with diaeresis
{"\xc4\x9b", '\xec'}, // e with caron
{"\xc3\xad", '\xed'}, // i with acute
{"\xc3\xae", '\xee'}, // i-circumflex
{"\xc4\x8f", '\xef'}, // d with caron
{"\xc4\x91", '\xf0'}, // crossed d
{"\xc5\x84", '\xf1'}, // n with acute
{"\xc5\x88", '\xf2'}, // n with caron
{"\xc3\xb3", '\xf3'}, // o with acute
{"\xc3\xb4", '\xf4'}, // o-circumflex
{"\xc5\x91", '\xf5'}, // o with double accent
{"\xc3\xb6", '\xf6'}, // o with diaeresis
{"\xc3\xb7", '\xf7'}, // division sign
{"\xc5\x99", '\xf8'}, // r with caron
{"\xc5\xaf", '\xf9'}, // u with diacritic
{"\xc3\xba", '\xfa'}, // u with acute
{"\xc5\xb1", '\xfb'}, // u with double accent
{"\xc3\xbc", '\xfc'}, // u with diaeresis
{"\xc3\xbd", '\xfd'}, // y with acute
{"\xc5\xa3", '\xfe'}, // t-cedilla
{"\xcb\x99", '\xff'}, // diactric dot
};
inline std::string win1250ToUTF8(const std::string& strRef)
{
std::string result;
result.reserve(strRef.size() * 2);
for (auto&& c : strRef)
{
if (WINDOWS1250_UTF8_MAP.contains(static_cast<unsigned char>(c)))
result += WINDOWS1250_UTF8_MAP.at(static_cast<unsigned char>(c));
else
result += c;
}
return result;
}
inline std::string UTF8ToWin1250(const std::string& strRef)
{
std::string result;
result.reserve(strRef.size());
size_t charSize = 1;
for (size_t i = 0; i < strRef.length(); ++i)
{
if (const int c = static_cast<unsigned char>(strRef[i]); c >= 128)
{
if (c < 224)
charSize = 2;
else if (c < 240)
charSize = 3;
else if (c < 248)
charSize = 4;
else if (c == 252)
charSize = 5;
else
charSize = 6;
}
// Update loop index according to UTF8 charSize;
i += charSize - 1;
if (charSize == 1)
{
result += strRef[i];
continue;
}
if (i + charSize > strRef.length())
{
result += '?';
return result;
}
String utfChar;
utfChar.reserve(charSize);
for (size_t j = 0; j < charSize; ++j)
{
utfChar += strRef[i + j];
}
if (UTF8_WINDOWS1250_MAP.contains(utfChar))
{
result += static_cast<char>(UTF8_WINDOWS1250_MAP.at(utfChar));
}
else
{
result += '?';
}
}
return result;
}
}
#endif // NONUT_CORE_STRING_HELPERS_H

View File

@@ -0,0 +1,22 @@
#ifndef NONUT_CORE_STRINGIFY_H
#define NONUT_CORE_STRINGIFY_H
#include "CommonHeader.h"
#define QUOTIFY(arg) #arg
#define STRINGIFY(arg) QUOTIFY(arg)
namespace nonut
{
template <typename T>
class Stringify
{
public:
virtual ~Stringify() = default;
[[nodiscard]] virtual String toString() const
{
return STRINGIFY(T);
}
};
}
#endif //NONUT_CORE_STRINGIFY_H

View File

@@ -0,0 +1,15 @@
#ifndef NONUT_CORE_USER_DATA_H
#define NONUT_CORE_USER_DATA_H
#include <sqapi.h>
namespace nonut
{
class UserData
{
public:
SQUserPointer userPtr = nullptr;
SQUserPointer tagPtr = nullptr;
};
}
#endif //NONUT_CORE_INSTANCE_H

View File

@@ -0,0 +1,108 @@
#ifndef NONUT_CORE_UTILS_H
#define NONUT_CORE_UTILS_H
#include "Instance.h"
#include "CommonHeader.h"
namespace nonut
{
struct CustomType
{
virtual void convert(HSQOBJECT object) = 0;
};
template <typename T>
void sqGetValue(SQVM* vm, SQInteger idx, T outPtr)
{
static_assert(
std::is_same_v<T, Bool*> ||
std::is_same_v<T, Int*> ||
std::is_same_v<T, Float*> ||
std::is_same_v<T, const SQChar**> ||
std::is_same_v<T, HSQOBJECT*> ||
std::is_same_v<T, SQUserPointer*>,
"Not supported return type");
if constexpr (std::is_same_v<T, Bool*>)
sq_getbool(vm, idx, outPtr);
if constexpr (std::is_same_v<T, Int*>)
sq_getinteger(vm, idx, outPtr);
if constexpr (std::is_same_v<T, Float*>)
sq_getfloat(vm, idx, outPtr);
if constexpr (std::is_same_v<T, const SQChar**>)
sq_getstring(vm, idx, outPtr);
if constexpr (std::is_same_v<T, HSQOBJECT*>)
{
sq_getstackobj(vm, idx, outPtr);
sq_addref(vm, outPtr);
}
if constexpr (std::is_same_v<T, SQUserPointer*>)
{
sq_getuserpointer(vm, idx, outPtr);
}
}
template <typename T>
void sqPushValue(SQVM* vm, T value)
{
static_assert(
std::is_same_v<T, bool> ||
std::is_same_v<T, Bool> ||
std::is_same_v<T, Int> ||
std::is_same_v<T, Float> ||
std::is_same_v<T, const SQChar*> ||
std::is_same_v<T, SQObject> ||
std::is_same_v<T, String> ||
std::is_same_v<T, String&> ||
std::is_same_v<T, SQUserPointer> ||
std::derived_from<T, Instance>,
"Not supported return type");
if constexpr (std::is_same_v<T, bool>)
sq_pushbool(vm, value);
if constexpr (std::is_same_v<T, Bool>)
sq_pushbool(vm, value);
if constexpr (std::is_same_v<T, Int>)
sq_pushinteger(vm, value);
if constexpr (std::is_same_v<T, Float>)
sq_pushfloat(vm, value);
if constexpr (std::is_same_v<T, SQChar*>)
sq_pushstring(vm, value, -1);
if constexpr (std::is_same_v<T, SQObject>)
sq_pushobject(vm, value);
if constexpr (std::is_same_v<T, String> || std::is_same_v<T, String&>)
sq_pushstring(vm, value.c_str(), value.length());
if constexpr (std::is_same_v<T, SQUserPointer>)
sq_pushuserpointer(vm, value);
if constexpr (std::derived_from<T, Instance>)
sq_pushobject(vm, value.getInstance());
}
template <typename T>
T returnVar()
{
HSQUIRRELVM vm = Sqrat::DefaultVM::Get();
static_assert(
std::is_same_v<T, SQObject> ||
std::is_same_v<T, Bool> ||
std::is_same_v<T, Float> ||
std::is_same_v<T, Int> ||
std::is_same_v<T, String>,
"Not supported return type");
T result{};
sqGetValue(vm, -1, &result);
sq_pop(vm, 1); // pops result
return result;
}
template <>
inline String returnVar<String>()
{
const SQChar* result = "";
sq_getstring(Sqrat::DefaultVM::Get(), -1, &result);
sq_pop(Sqrat::DefaultVM::Get(), 1); // pops result
return result;
}
}
#endif // NONUT_CORE_UTILS_H

View File

@@ -0,0 +1,20 @@
#include "CommonHeader.h"
#include "Array.h"
namespace nonut
{
Array::Array(const SQObject object) : object(object), cachedSize(size())
{
}
Array::~Array() = default;
size_t Array::size() const
{
HSQUIRRELVM vm = Sqrat::DefaultVM::Get();
sq_pushobject(vm, object);
const auto result = sq_getsize(vm, -1);
sq_pop(vm, 1);
return static_cast<size_t>(result);
}
}

View File

@@ -0,0 +1,69 @@
#include "CommonHeader.h"
#include "Class.h"
namespace nonut
{
Class::Class(const String& className, const SQObject classObjectInstance)
{
HSQUIRRELVM vm = Sqrat::DefaultVM::Get();
if (classObjectInstance._type == OT_NULL)
{
bIsNull = true;
const auto top = sq_gettop(vm);
sq_pushroottable(vm); //push root table
sq_pushstring(vm, className.c_str(), className.length()); //push class name
if (sq_get(vm, -2) == SQ_OK) //retrieve class
{
sq_getstackobj(vm, -1, &classObject);
sq_addref(vm, &classObject);
if (sq_createinstance(vm, -1) == SQ_OK) //create class instance
{
//1. Get object ptr
sq_getstackobj(vm, -1, &this->classObjectInstance); //retrieve object
sq_addref(vm, &this->classObjectInstance);
//Add ref thanks to which object will not be immediately deleted
sq_pop(vm, 1); // pop class instance
}
}
sq_settop(vm, top); // TODO: FIX LEAK PROPERLY
}
else
{
this->classObjectInstance = classObjectInstance;
const auto top = sq_gettop(vm);
sq_addref(vm, &this->classObjectInstance);
sq_pushroottable(vm); //push root table
sq_pushstring(vm, className.c_str(), className.length()); //push class name
if (sq_get(vm, -2) == SQ_OK) //retrieve class
{
sq_getstackobj(vm, -1, &classObject);
sq_addref(vm, &classObject);
}
sq_settop(vm, top);
}
}
Class::~Class()
{
HSQUIRRELVM vm = Sqrat::DefaultVM::Get();
sq_release(vm, &classObject);
sq_release(vm, &classObjectInstance);
sq_resetobject(&classObject);
sq_resetobject(&classObjectInstance);
}
SQObject Class::getInstance() const
{
return classObjectInstance;
}
bool Class::isNull() const
{
return bIsNull;
}
}

View File

@@ -0,0 +1,14 @@
#include "Constant.h"
namespace nonut
{
SQObject getConstTable()
{
SQObject obj;
HSQUIRRELVM vm = Sqrat::DefaultVM::Get();
sq_pushconsttable(vm);
sq_getstackobj(vm, -1, &obj);
sq_pop(vm, 1); // No addref needed, since the consttable is always around
return obj;
}
}

View File

@@ -0,0 +1,181 @@
#include "CustomTypes.h"
#include "Array.h"
#include "Property.h"
namespace nonut
{
#define GET_SLOT(slot, type) slot = arrayWrapper.get<type>(#slot)
void GameTime::convert(SQObject object)
{
Array arrayWrapper(object);
GET_SLOT(day, Int);
GET_SLOT(hour, Int);
GET_SLOT(min, Int);
}
void Position2d::convert(SQObject object)
{
Array arrayWrapper(object);
GET_SLOT(x, Int);
GET_SLOT(y, Int);
}
void Position3d::convert(SQObject object)
{
Array arrayWrapper(object);
GET_SLOT(x, Float);
GET_SLOT(y, Float);
GET_SLOT(z, Float);
}
void Size2d::convert(SQObject object)
{
Array arrayWrapper(object);
GET_SLOT(width, Int);
GET_SLOT(height, Int);
}
void Rect::convert(SQObject object)
{
Array arrayWrapper(object);
GET_SLOT(x, Int);
GET_SLOT(y, Int);
GET_SLOT(width, Int);
GET_SLOT(height, Int);
}
void UV::convert(SQObject object)
{
Array arrayWrapper(object);
GET_SLOT(x, Float);
GET_SLOT(y, Float);
GET_SLOT(width, Float);
GET_SLOT(height, Float);
}
void Resolution::convert(SQObject object)
{
Array arrayWrapper(object);
GET_SLOT(x, Int);
GET_SLOT(y, Int);
GET_SLOT(bpp, Int);
}
void Item::convert(SQObject object)
{
Array arrayWrapper(object);
GET_SLOT(instance, Int);
GET_SLOT(amount, Int);
GET_SLOT(name, String);
}
void Color::convert(SQObject object)
{
Array arrayWrapper(object);
GET_SLOT(r, Int);
GET_SLOT(g, Int);
GET_SLOT(b, Int);
}
void BodyVisual::convert(SQObject object)
{
Array arrayWrapper(object);
GET_SLOT(bodyModel, String);
GET_SLOT(bodyTxt, Int);
GET_SLOT(headModel, String);
GET_SLOT(headTxt, Int);
}
void NetworkStats::convert(SQObject object)
{
Array arrayWrapper(object);
GET_SLOT(packetReceived, Int);
GET_SLOT(packetlossTotal, Int);
GET_SLOT(packetlossLastSecond, Int);
GET_SLOT(messagesInResendBuffer, Int);
GET_SLOT(messageInSendBuffer, Int);
GET_SLOT(bytesInResendBuffer, Int);
GET_SLOT(bytesInSendBuffer, Int);
}
void Position3dWithName::convert(SQObject object)
{
Array arrayWrapper(object);
GET_SLOT(name, String);
GET_SLOT(x, Float);
GET_SLOT(y, Float);
GET_SLOT(z, Float);
}
void SqDict::convert(SQObject object)
{
Sqrat::Table tab = Sqrat::Table(object);
Sqrat::Object::iterator tabIterator;
int i = 0;
while (tab.Next(tabIterator))
{
HSQOBJECT key = tabIterator.getKey();
HSQOBJECT value = tabIterator.getValue();
if (key._type != OT_STRING)
continue;
if (value._type == OT_STRING)
data[sq_objtostring(&key)] = sq_objtostring(&value);
else if (value._type == OT_INTEGER)
data[sq_objtostring(&key)] = sq_objtointeger(&value);
else if (value._type == OT_FLOAT)
data[sq_objtostring(&key)] = sq_objtofloat(&value);
else if (value._type == OT_TABLE)
{
SqDict result = SqDict();
result.convert(value);
data[sq_objtostring(&key)] = result.data;
}
else if (value._type == OT_ARRAY)
{
SqList result = SqList();
result.convert(value);
data[sq_objtostring(&key)] = result.data;
}
}
}
void SqList::convert(SQObject object)
{
Sqrat::Array tab = Sqrat::Array(object);
Sqrat::Object::iterator arrIterator;
int i = 0;
while (tab.Next(arrIterator))
{
HSQOBJECT key = arrIterator.getKey();
HSQOBJECT value = arrIterator.getValue();
if (key._type != OT_INTEGER)
continue;
if (value._type == OT_STRING)
data.insert(sq_objtointeger(&key), sq_objtofloat(&value));
else if (value._type == OT_INTEGER)
data.insert(sq_objtointeger(&key), sq_objtointeger(&value));
else if (value._type == OT_FLOAT)
data.insert(sq_objtointeger(&key), sq_objtofloat(&value));
else if (value._type == OT_TABLE)
{
SqDict result = SqDict();
result.convert(value);
data.insert(sq_objtointeger(&key), result.data);
}
else if (value._type == OT_ARRAY)
{
SqList result = SqList();
result.convert(value);
data.insert(sq_objtointeger(&key), result.data);
}
}
}
}

View File

@@ -0,0 +1,32 @@
#include "StaticClass.h"
namespace nonut
{
StaticClass::StaticClass(const String& className)
{
HSQUIRRELVM vm = Sqrat::DefaultVM::Get();
const auto top = sq_gettop(vm);
sq_pushroottable(vm); //push root table
sq_pushstring(vm, className.c_str(), className.length()); //push class instance name
if (sq_get(vm, -2) == SQ_OK) //retrieve class instance
{
sq_getstackobj(vm, -1, &classObjectInstance);
sq_addref(vm, &classObjectInstance);
sq_getclass(vm, -1);
sq_getstackobj(vm, -1, &classObject);
sq_addref(vm, &classObject);
}
sq_settop(vm, top); // TODO: FIX LEAK PROPERLY
}
StaticClass::~StaticClass()
{
HSQUIRRELVM vm = Sqrat::DefaultVM::Get();
sq_release(vm, &classObject);
sq_release(vm, &classObjectInstance);
sq_resetobject(&classObject);
sq_resetobject(&classObjectInstance);
}
}