1
0
mirror of https://github.com/0O0o0oOoO00/Alas.git synced 2026-05-14 14:49:25 +08:00

add: base framework for gamefree

This commit is contained in:
0O0o0oOoO00
2025-08-02 18:08:20 +08:00
parent 98c230bfd9
commit 2724a01243
9 changed files with 180 additions and 0 deletions

View File

@@ -17,6 +17,12 @@ class ByteArray:
def writeUInt(self, data: ctypes.c_uint) -> ByteArray:
...
def writeUInt8(self, data: ctypes.c_uint8) -> ByteArray:
...
def writeUInt16(self, data: ctypes.c_uint16) -> ByteArray:
...
def writeLong(self, data: ctypes.c_long) -> ByteArray:
...

View File

@@ -21,6 +21,14 @@ void ByteArray::writeUInt(unsigned int data) {
writeNumber(data);
}
void ByteArray::writeUInt8(unsigned _int8 data) {
writeNumber(data);
}
void ByteArray::writeUInt16(unsigned _int16 data) {
writeNumber(data);
}
void ByteArray::writeLong(long data) {
writeNumber(data);
}

View File

@@ -25,6 +25,10 @@ public:
void writeUInt(unsigned int data);
void writeUInt8(unsigned _int8 data);
void writeUInt16(unsigned _int16 data);
void writeLong(long data);
void writeLongLong(long long data);

View File

@@ -20,6 +20,16 @@ PyByteArray& PyByteArray::writeUInt(unsigned int data) {
return *this;
}
PyByteArray& PyByteArray::writeUInt8(unsigned _int8 data) {
m_data.writeUInt8(data);
return *this;
}
PyByteArray& PyByteArray::writeUInt16(unsigned _int16 data) {
m_data.writeUInt16(data);
return *this;
}
PyByteArray& PyByteArray::writeLong(long data) {
m_data.writeLong(data);
return *this;

View File

@@ -15,6 +15,10 @@ public:
PyByteArray& writeUInt(unsigned int data);
PyByteArray& writeUInt8(unsigned _int8 data);
PyByteArray& writeUInt16(unsigned _int16 data);
PyByteArray& writeLong(long data);
PyByteArray& writeLongLong(long long data);

View File

@@ -11,6 +11,8 @@ PYBIND11_MODULE(bytearray, m) {
.def("writeUChar", &PyByteArray::writeUChar)
.def("writeInt", &PyByteArray::writeInt)
.def("writeUInt", &PyByteArray::writeUInt)
.def("writeUInt8", &PyByteArray::writeUInt8)
.def("writeUInt16", &PyByteArray::writeUInt16)
.def("writeLong", &PyByteArray::writeLong)
.def("writeLongLong", &PyByteArray::writeLongLong)
.def("writeULong", &PyByteArray::writeULong)

View File

@@ -0,0 +1,16 @@
class AzurLaneGameDataManager:
instance = None
def __init__(self):
...
@staticmethod
def get_instance() -> "AzurLaneGameDataManager":
if AzurLaneGameDataManager.instance is None:
AzurLaneGameDataManager.instance = AzurLaneGameDataManager()
return AzurLaneGameDataManager.instance
class AzurLaneGameData:
def __init__(self):
self.game_data = AzurLaneGameDataManager.get_instance()

37
module/gamefree/netpkg.py Normal file
View File

@@ -0,0 +1,37 @@
import threading
from google.protobuf import message
import module.gamefree.bytearray as ba
class AzurLaneNetworkEndPackage:
...
class AzurLaneNetworkPackage:
def __init__(self, id, proto_message: message.Message):
self.event = threading.Event()
self.proto_message = proto_message
self.id = id
self.returned_data: bytes = None
def pack(self) -> bytes:
buffer = ba.ByteArray()
serialized = self.proto_message.SerializeToString()
serialized_len = len(serialized)
if serialized_len == 0:
buffer.writeUInt16(6)
else:
buffer.writeUInt16(5 + serialized_len)
buffer.writeUInt8(0)
buffer.writeUInt16(self.id)
buffer.writeUInt16(0)
buffer.writeString(serialized)
return buffer.toBytes()
class HeartBeatPackage:
...

View File

@@ -0,0 +1,93 @@
import socket
import threading
import time
from queue import Queue
from module.gamefree.netpkg import *
from module.logger import logger
class AzurLaneNetworkClient:
instance = None
def __init__(self):
self.task_queue = Queue()
self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.worker: threading.Thread = None
self.heartbeater: threading.Thread = None
self.heartbeat_thread_event = threading.Event()
def __del__(self):
self.stop_work()
def connect(self, addr, port):
self.server_socket.connect((addr, port))
def transfer(self, pkg: AzurLaneNetworkPackage) -> bytes:
self.server_socket.send(pkg.pack())
buffer = ba.ByteArray()
while 1:
returned_data = self.server_socket.recv(1024)
if returned_data == 0:
break
buffer.writeBytes(returned_data)
return buffer.toBytes()
def start_heartbeat(self):
if self.heartbeater is not None:
if self.heartbeater.is_alive():
return
self.heartbeater = threading.Thread(target=self.work_thread)
self.heartbeater.start()
def start_work(self):
if self.worker is not None:
if self.worker.is_alive():
return
self.worker = threading.Thread(target=self.work_thread)
self.worker.start()
def stop_work(self):
self.heartbeat_thread_event.set()
self.task_queue.queue.clear()
self.task_queue.put(AzurLaneNetworkEndPackage())
def work_thread(self):
while 1:
pkg = self.task_queue.get()
if isinstance(pkg, AzurLaneNetworkEndPackage):
break
elif isinstance(pkg, AzurLaneNetworkPackage):
data = self.transfer(pkg)
pkg.returned_data = data
pkg.event.set()
else:
logger.warning(f"Unknown net package class: {type(pkg).__name__}")
def heartbeat_thread(self):
while 1:
if self.heartbeat_thread_event.is_set():
break
self.task_queue.put(HeartBeatPackage())
if self.heartbeat_thread_event.is_set():
break
time.sleep(1)
def queue_package(self, pkg):
self.task_queue.put(pkg)
@staticmethod
def get_instance() -> "AzurLaneNetworkClient":
if AzurLaneNetworkClient.instance is None:
AzurLaneNetworkClient.instance = AzurLaneNetworkClient()
return AzurLaneNetworkClient.instance
class AzurLaneNetwork:
def __init__(self):
self.client = AzurLaneNetworkClient.get_instance()
def send(self, pkg: AzurLaneNetworkPackage) -> bytes:
self.client.queue_package(pkg)
pkg.event.wait()
return pkg.returned_data