diff --git a/.gitignore b/.gitignore index 1b35331b1..16c3e39cb 100644 --- a/.gitignore +++ b/.gitignore @@ -284,4 +284,9 @@ blcrack/cracker/webpage.cpp blcrack/cracker/webui/node_modules/ blcrack/cracker/webui/dist/ blcrack/cracker/webui/.vscode/ -blcrack/cracker/webui/.idea/ \ No newline at end of file +blcrack/cracker/webui/.idea/ + +module/gamefree/pybind11/ +module/gamefree/cmake-build-*/ +module/gamefree/bytearray*.pyd +python/ \ No newline at end of file diff --git a/module/gamefree/CMakeLists.txt b/module/gamefree/CMakeLists.txt new file mode 100644 index 000000000..7e1b2dcb5 --- /dev/null +++ b/module/gamefree/CMakeLists.txt @@ -0,0 +1,14 @@ +cmake_minimum_required(VERSION 3.28) + +project(gamefree) + +set(CMAKE_CXX_STANDARD 26) + +set(PYTHON_DIR ${CMAKE_CURRENT_LIST_DIR}/../../python) + +set(PYBIND11_INSTALL OFF) +set(PYBIND11_TEST OFF) +set(PYTHON_EXECUTABLE ${PYTHON_DIR}/3.7.6/python.exe) +add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/pybind11) + +add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/bytearray) \ No newline at end of file diff --git a/module/gamefree/bytearray.pyi b/module/gamefree/bytearray.pyi new file mode 100644 index 000000000..f4900a450 --- /dev/null +++ b/module/gamefree/bytearray.pyi @@ -0,0 +1,54 @@ +import ctypes + + +class ByteArray: + def __init__(self): + ... + + def writeChar(self, data: ctypes.c_char) -> ByteArray: + ... + + def writeUChar(self, data: ctypes.c_ubyte) -> ByteArray: + ... + + def writeInt(self, data: ctypes.c_int) -> ByteArray: + ... + + def writeUInt(self, data: ctypes.c_uint) -> ByteArray: + ... + + def writeLong(self, data: ctypes.c_long) -> ByteArray: + ... + + def writeLongLong(self, data: ctypes.c_longlong) -> ByteArray: + ... + + def writeULong(self, data: ctypes.c_ulong) -> ByteArray: + ... + + def writeULongLong(self, data: ctypes.c_ulonglong) -> ByteArray: + ... + + def writeFloat(self, data: ctypes.c_float) -> ByteArray: + ... + + def writeDouble(self, data: ctypes.c_double) -> ByteArray: + ... + + def writeLongDouble(self, data: ctypes.c_longdouble) -> ByteArray: + ... + + def writeBool(self, data: ctypes.c_bool) -> ByteArray: + ... + + def writeString(self, data: str) -> ByteArray: + ... + + def writeBytes(self, data: bytes) -> ByteArray: + ... + + def toString(self) -> str: + ... + + def toBytes(self) -> bytes: + ... diff --git a/module/gamefree/bytearray/ByteArray.cpp b/module/gamefree/bytearray/ByteArray.cpp new file mode 100644 index 000000000..d386d7dcd --- /dev/null +++ b/module/gamefree/bytearray/ByteArray.cpp @@ -0,0 +1,70 @@ +#include "ByteArray.hpp" + +void ByteArray::writeContinuousData(const void* data, size_t length) { + auto p = reinterpret_cast(data); + m_data.insert(m_data.end(), p, p + length); +} + +void ByteArray::writeChar(char data) { + writeNumber(data); +} + +void ByteArray::writeUChar(unsigned char data) { + writeNumber(data); +} + +void ByteArray::writeInt(int data) { + writeNumber(data); +} + +void ByteArray::writeUInt(unsigned int data) { + writeNumber(data); +} + +void ByteArray::writeLong(long data) { + writeNumber(data); +} + +void ByteArray::writeLongLong(long long data) { + writeNumber(data); +} + +void ByteArray::writeULong(unsigned long data) { + writeNumber(data); +} + +void ByteArray::writeULongLong(unsigned long long data) { + writeNumber(data); +} + +void ByteArray::writeFloat(float data) { + writeNumber(data); +} + +void ByteArray::writeDouble(double data) { + writeNumber(data); +} + +void ByteArray::writeLongDouble(long double data) { + writeNumber(data); +} + +void ByteArray::writeBool(bool data) { + writeNumber(data); +} + +void ByteArray::writeString(const std::string_view& string) { + writeContinuousData(string.data(), string.size()); +} + +void ByteArray::writeBytes(const char* data, size_t length) { + writeContinuousData(data, length); +} + +std::string ByteArray::toString() const { + return std::string(m_data.data(), m_data.size()); +} + +const std::vector& ByteArray::data() const { + return m_data; +} diff --git a/module/gamefree/bytearray/ByteArray.hpp b/module/gamefree/bytearray/ByteArray.hpp new file mode 100644 index 000000000..07e920ea6 --- /dev/null +++ b/module/gamefree/bytearray/ByteArray.hpp @@ -0,0 +1,57 @@ +#ifndef BYTEARRAY_HPP +#define BYTEARRAY_HPP + +#include +#include +#include +#include + +class ByteArray { +public: + template + void writeNumber(T data) { + T d = data; + auto p = reinterpret_cast(&d); + m_data.insert(m_data.end(), p, p + sizeof(d)); + } + + void writeContinuousData(const void* data, size_t length); + + void writeChar(char data); + + void writeUChar(unsigned char data); + + void writeInt(int data); + + void writeUInt(unsigned int data); + + void writeLong(long data); + + void writeLongLong(long long data); + + void writeULong(unsigned long data); + + void writeULongLong(unsigned long long data); + + void writeFloat(float data); + + void writeDouble(double data); + + void writeLongDouble(long double data); + + void writeBool(bool data); + + void writeString(const std::string_view& string); + + void writeBytes(const char* data, size_t length); + + std::string toString() const; + + const std::vector& data() const; + +private: + std::vector m_data; +}; + + +#endif //BYTEARRAY_HPP diff --git a/module/gamefree/bytearray/CMakeLists.txt b/module/gamefree/bytearray/CMakeLists.txt new file mode 100644 index 000000000..ebea35ace --- /dev/null +++ b/module/gamefree/bytearray/CMakeLists.txt @@ -0,0 +1,6 @@ +file(GLOB bytearray_src + ${CMAKE_CURRENT_LIST_DIR}/*.hpp + ${CMAKE_CURRENT_LIST_DIR}/*.cpp +) + +pybind11_add_module(bytearray ${bytearray_src}) \ No newline at end of file diff --git a/module/gamefree/bytearray/PyByteArray.cpp b/module/gamefree/bytearray/PyByteArray.cpp new file mode 100644 index 000000000..27a396d10 --- /dev/null +++ b/module/gamefree/bytearray/PyByteArray.cpp @@ -0,0 +1,82 @@ +#include "PyByteArray.hpp" + +PyByteArray& PyByteArray::writeChar(char data) { + m_data.writeChar(data); + return *this; +} + +PyByteArray& PyByteArray::writeUChar(unsigned char data) { + m_data.writeUChar(data); + return *this; +} + +PyByteArray& PyByteArray::writeInt(int data) { + m_data.writeInt(data); + return *this; +} + +PyByteArray& PyByteArray::writeUInt(unsigned int data) { + m_data.writeUInt(data); + return *this; +} + +PyByteArray& PyByteArray::writeLong(long data) { + m_data.writeLong(data); + return *this; +} + +PyByteArray& PyByteArray::writeLongLong(long long data) { + m_data.writeLongLong(data); + return *this; +} + +PyByteArray& PyByteArray::writeULong(unsigned long data) { + m_data.writeULong(data); + return *this; +} + +PyByteArray& PyByteArray::writeULongLong(unsigned long long data) { + m_data.writeULongLong(data); + return *this; +} + +PyByteArray& PyByteArray::writeFloat(float data) { + m_data.writeFloat(data); + return *this; +} + +PyByteArray& PyByteArray::writeDouble(double data) { + m_data.writeDouble(data); + return *this; +} + +PyByteArray& PyByteArray::writeLongDouble(long double data) { + m_data.writeLongDouble(data); + return *this; +} + +PyByteArray& PyByteArray::writeBool(bool data) { + m_data.writeBool(data); + return *this; +} + +PyByteArray& PyByteArray::writeString(const std::string_view& string) { + m_data.writeString(string); + return *this; +} + +PyByteArray& PyByteArray::writeBytes(const pybind11::bytes& data) { + auto size = PYBIND11_BYTES_SIZE(data.ptr()); + auto buffer = PYBIND11_BYTES_AS_STRING(data.ptr()); + m_data.writeBytes(buffer, size); + return *this; +} + +std::string PyByteArray::toString() const { + return m_data.toString(); +} + +pybind11::bytes PyByteArray::toBytes() const { + const auto& d = m_data.data(); + return pybind11::bytes(d.data(), d.size()); +} diff --git a/module/gamefree/bytearray/PyByteArray.hpp b/module/gamefree/bytearray/PyByteArray.hpp new file mode 100644 index 000000000..cda4a28b6 --- /dev/null +++ b/module/gamefree/bytearray/PyByteArray.hpp @@ -0,0 +1,47 @@ +#ifndef PYBYTEARRAY_HPP +#define PYBYTEARRAY_HPP + +#include + +#include "ByteArray.hpp" + +class PyByteArray { +public: + PyByteArray& writeChar(char data); + + PyByteArray& writeUChar(unsigned char data); + + PyByteArray& writeInt(int data); + + PyByteArray& writeUInt(unsigned int data); + + PyByteArray& writeLong(long data); + + PyByteArray& writeLongLong(long long data); + + PyByteArray& writeULong(unsigned long data); + + PyByteArray& writeULongLong(unsigned long long data); + + PyByteArray& writeFloat(float data); + + PyByteArray& writeDouble(double data); + + PyByteArray& writeLongDouble(long double data); + + PyByteArray& writeBool(bool data); + + PyByteArray& writeString(const std::string_view& string); + + PyByteArray& writeBytes(const pybind11::bytes& data); + + std::string toString() const; + + pybind11::bytes toBytes() const; + +private: + ByteArray m_data; +}; + + +#endif //PYBYTEARRAY_HPP diff --git a/module/gamefree/bytearray/module.cpp b/module/gamefree/bytearray/module.cpp new file mode 100644 index 000000000..ca10a30d3 --- /dev/null +++ b/module/gamefree/bytearray/module.cpp @@ -0,0 +1,26 @@ +#include + +#include "PyByteArray.hpp" + +PYBIND11_MODULE(bytearray, m) { + namespace py = pybind11; + + py::class_(m, "ByteArray") + .def(py::init()) + .def("writeChar", &PyByteArray::writeChar) + .def("writeUChar", &PyByteArray::writeUChar) + .def("writeInt", &PyByteArray::writeInt) + .def("writeUInt", &PyByteArray::writeUInt) + .def("writeLong", &PyByteArray::writeLong) + .def("writeLongLong", &PyByteArray::writeLongLong) + .def("writeULong", &PyByteArray::writeULong) + .def("writeULongLong", &PyByteArray::writeULongLong) + .def("writeFloat", &PyByteArray::writeFloat) + .def("writeDouble", &PyByteArray::writeDouble) + .def("writeLongDouble", &PyByteArray::writeLongDouble) + .def("writeBool", &PyByteArray::writeBool) + .def("writeString", &PyByteArray::writeString) + .def("writeBytes", &PyByteArray::writeBytes) + .def("toString", &PyByteArray::toString) + .def("toBytes", &PyByteArray::toBytes); +} diff --git a/module/gamefree/genpb.py b/module/gamefree/genpb.py new file mode 100644 index 000000000..d7d3b32b7 --- /dev/null +++ b/module/gamefree/genpb.py @@ -0,0 +1,26 @@ +import glob +import os.path +from pathlib import Path + +from grpc_tools import protoc + + +def main(): + self_dir = Path(__file__).parent + pb_dir = self_dir / "pb" + if not os.path.exists(pb_dir): + os.makedirs(pb_dir) + + proto_dir = self_dir / ".." / ".." / "blcrack" / "cracker" / "proto" + protos = glob.glob(f"{str(proto_dir)}/*.proto") + cmd = [ + "grpc_tools.protoc", + f"--python_out={str(pb_dir)}", + f"--pyi_out={str(pb_dir)}", + f"--proto_path={str(proto_dir)}", + ] + protoc.main(cmd + protos) + + +if __name__ == "__main__": + main()