update network class

This commit is contained in:
AleaJactaEst 2020-03-30 22:20:59 +02:00
parent dca2fb7a9a
commit 24a9e32644
21 changed files with 2014 additions and 520 deletions

View file

@ -31,6 +31,39 @@ variables:
XDG_CONFIG_HOME: '/tmp/config' XDG_CONFIG_HOME: '/tmp/config'
DOCKER_GODOT_SOURCE: '/root/workspace/godot/' DOCKER_GODOT_SOURCE: '/root/workspace/godot/'
Build Client Linux 64 (Quater):
# ERROR: _load: No loader found for resource: res://assets/GUI/images/Login-Khanat-background.png
stage: build
tags:
- Docker
image: amd64/debian:10
script:
- export -p WORKDIR=$PWD
- apt-get update
- apt-get dist-upgrade -y
- DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y scons git g++ wget unzip ca-certificates python python-openssl
- DEBIAN_FRONTEND=noninteractive apt-get install -y xvfb libxcursor1 libxinerama1 libxrandr2 libxi6 libasound2 libpulse0 libgl1 mesa-utils libgl1-mesa-dri libasound2 libasound2-plugins alsa-utils alsa-oss pulseaudio pulseaudio-utils
- DEBIAN_FRONTEND=noninteractive apt-get install -y xterm libxcursor1 xcursor-themes icon-slicer libpulse0
- DEBIAN_FRONTEND=noninteractive apt-get install -y lxde strace
- DEBIAN_FRONTEND=noninteractive apt-get install -y task-gnome-desktop
- DEBIAN_FRONTEND=noninteractive apt-get install -y xvfb libxcursor-dev libxinerama1 libxrandr2 libxi6 libasound2 libpulse0 libgl1-mesa-glx
- DEBIAN_FRONTEND=noninteractive apt-get install -y x11-xkb-utils xfonts-100dpi xfonts-75dpi xfonts-scalable xfonts-cyrillic x11-apps
- mkdir -p build
- (cd build; git clone https://github.com/godotengine/godot.git && cd godot && git checkout 3.2)
- (cd build/godot; for file in ../../../modules/*; do if [ -d $file ];then ln -s $file .; fi; done)
- (cd build/godot; cp modules/*/doc_classes/* doc/classes/.)
- (cd build/godot; scons -j$(nproc) platform=x11)
- build/godot/bin/godot --editor --quit
- build/godot/bin/godot --quit -v --path $WORKDIR --export khaganat.linux.64 khaganat.linux64.bin
- ls -la assets/GUI/images/
- ls -la .import/ || echo ""
- ls -la || echo ""
artifacts:
name: "khanat-$(echo $CI_BUILD_REF | head -c 7 )-$CI_PIPELINE_ID-client-linux-64"
paths:
- khaganat.linux64.*
when: manual
Build Client Linux 64 (Ter): Build Client Linux 64 (Ter):
# ERROR: _load: No loader found for resource: res://assets/GUI/images/Login-Khanat-background.png # ERROR: _load: No loader found for resource: res://assets/GUI/images/Login-Khanat-background.png
stage: build stage: build

135
README.md
View file

@ -1,6 +1,6 @@
# Build # Build
Before build and launch client, we need build godot-cpp (lib to connect c++ code to godot engine) and build crypt (c++ module use to authentification with khaganat) Before build and launch client, build module (before, we need include modules on godot source)
## Build module ## Build module
@ -31,7 +31,8 @@ cp modules/*/doc_classes/* doc/classes/.
# Clean project (if you build before) # Clean project (if you build before)
scons -j$(nproc) -c scons -j$(nproc) -c
# Build # Build
scons -j$(nproc) platform=x11 scons -j$(nproc) platform=x11 target=debug
scons -j$(nproc) platform=x11 target=release_debug
cd ../.. cd ../..
``` ```
@ -51,46 +52,6 @@ bin/godot.x11.tools.64
cd ../.. cd ../..
``` ```
## Build godot-cpp
### Initialize
Load git submodule (godot-cpp & godot_header)
```
git submodule update --init --recursive
```
### Build on 64bits
```
godot --gdnative-generate-json-api godot-cpp/godot_headers/api.json
scons -C godot-cpp platform=linux generate_bindings=yes custom_api_file=godot_headers/api.json bits=64
```
### Build on 32bits
```
godot --gdnative-generate-json-api godot-cpp/godot_headers/api.json
scons -C godot-cpp platform=linux generate_bindings=yes custom_api_file=godot_headers/api.json bits=32
```
## Build gdnative (crypt / bitstream / bitset)
### Build on 64bits
```
scons -C gdnative platform=linux bits=64 target=debug
scons -C gdnative platform=linux bits=64 target=release
```
### Build on 32bits
```
scons -C gdnative platform=linux bits=32 target=debug
scons -C gdnative platform=linux bits=64 target=release
```
## Package client khaganat ## Package client khaganat
### Configure export ### Configure export
@ -137,3 +98,93 @@ godot --path . --export khaganat.linux.64 khaganat.linux64.bin
``` ```
godot login_scene/login_scene.tsc godot login_scene/login_scene.tsc
``` ```
## Library
### NetworkConnection
NetworkConnection -> class to manage/use NetworkConnectionCore
All times, connect on NetworkConnectionCore (to get singleton) and launch function
The goal is to don't managed Singleton, this class manage
At end of program, you need execute function "terminate_network_connection" to remove singleton.
NetworkConnectionCore -> class Singleton (uniq object) [contains network connexion, state connexion]
_state_connexion[StateConnectionBase] : Object change class with state connexion [StateConnectionNotInitialized, StateConnectionLogin, StateConnectionSynchronize, StateConnectionConnected, StateConnectionQuit]
_network_data [NetworkData] : Object state connexion (Tick receive, send, bit acknowledge)
_queue [BitStreamQueue] : queue to store message UDP (just simple method to try re-order message receive by UDP)
_socketUDP [Ref<PacketPeerUDP>] : network connexion
NetworkConnection(object A) NetworkConnection(object B) ...
| |
+-------+----+---------------------------------------+-----------------------------------------+
|
NetworkConnectionCore
* _network_data
* _queue
* _socketUDP
* _state_connexion
if StateConnectionConnected
### ReferentialMessage
ReferentialMessage -> class to manage/use ReferentialMessageCore
ReferentialMessageCore -> class singleton (uniq object) [Manage data provide by msg.xml], we can encode/decode khaganat's message
### ViewMessage
PacketServer
+---------+ +---------+ +---------+
| Level A | | Level B | | Level C |
| (0) | | (0) | | (0) |
+---------+ +---------+ +---------+
+---------+ +---------+
| Level B | | Level C |
| (1) | | (1) |
+---------+ +---------+
+---------+
| Level C |
| (2) |
+---------+
+---------+
| Level C |
| (3) |
+---------+
Message UDP :
+-------------+
| Server Part |
+-------------+
| Type Message (system / application) |
+---------+
| | +----------------+
| | -> | System Message |
| Message | +----------------+
| |
| UDP | +----------------+ +---------+ +---------+ +---------+
| | -> | Normal Message | -> | Level A +-+ Level B +-+ Level C +
| | +----------------+ +---------+ +---------+ +---------+
+---------+
Message UDP :
+-------------------+------------+---
| CurrentSendNumber | SystemMode | . . .
| 32 bits | 1 bit |
+-+-+-+-+-+-+-+-+-+-+------------+---
1 -> system mode
0 -> normal mode
System Message :
+---------+--
| Message | . . .
| 8 bits |
+---------+--

47
TODO
View file

@ -4,3 +4,50 @@
* Execute next step - UDP module to communicate with khaganat * Execute next step - UDP module to communicate with khaganat
* Configuration panel to define all connexion parameter * Configuration panel to define all connexion parameter
* Path : check version and patch all file (we need generate path file for godot and method to reload data) * Path : check version and patch all file (we need generate path file for godot and method to reload data)
#####################
# Debug CI
#####################
https://github.com/aBARICHELLO/godot-ci/blob/master/Dockerfile
https://github.com/aBARICHELLO/godot-ci/blob/master/.gitlab-ci.yml
https://github.com/h4de5/docker-godot-3-build-and-run/blob/master/Dockerfile
docker run -it -v ~/Projets/khanat/temp/build:/build amd64/debian:10 /bin/bash
docker run -it -v ~/Projets/khanat/temp/build2:/build amd64/debian:10 /bin/bash
gitlab-runner exec docker --timeout=3600 --docker-volumes $HOME/Projets/khanat/temp/build2:/builds 'Build Client Linux 64'
apt-get install build-essential scons pkg-config libx11-dev libxcursor-dev libxinerama-dev \
libgl1-mesa-dev libglu-dev libasound2-dev libpulse-dev libfreetype6-dev libudev-dev libxi-dev \
libxrandr-dev yasm
git clone https://github.com/godotengine/godot.git
scons -j8 platform=x11 tools=no target=release bits=64
scons -j8 platform=x11 tools=yes target=release bits=64
scons -j8 platform=server tools=no target=release bits=64
scons -j8 platform=server tools=yes target=release bits=64
(cd /build/0/godot/; scons -j8 platform=server tools=yes target=debug bits=64)
/build/0/godot/bin/godot_server.x11.tools.64 -v --path /build/0/project-0 --export khaganat.linux.64 khaganat.linux64.bin
apt-get install lxde x11vnc
apt-get install x11vnc mesa-utils libgl1-mesa-dri
apt-get install -y xvfb libxcursor1 libxinerama1 libxrandr2 libxi6 libasound2 libpulse0 libgl1 mesa-utils libgl1-mesa-dri libasound2 libasound2-plugins alsa-utils alsa-oss pulseaudio pulseaudio-utils
xvfb-run -a -n 99 --server-args="-screen 0 1024x768x24"
xvfb
pulseaudio -D
xvfb-run -a -n 99 --server-args="-ac -screen 0 1024x768x24" /build/0/godot/bin/godot.x11.opt.64 -v --path . --export khaganat.linux.64 khaganat.linux64.bin
xvfb-run -a -n 99 --server-args="-ac -screen 0 1024x768x24" /usr/local/bin/godot --quit -v --path . --export khaganat.linux.64 khaganat.linux64.bin

View file

@ -25,60 +25,67 @@ func open_message_xml():
func is_correct_md5(value): func is_correct_md5(value):
return (_msg_md5sum == value) return (_msg_md5sum == value)
func load_node(_msg_xml, level):
var ret = _msg_xml.read()
var i
var name
var index = 0
var dico = {}
while ret == OK:
match _msg_xml.get_node_type():
XMLParser.NODE_NONE: # 0
# print("NODE_NONE")
pass
XMLParser.NODE_ELEMENT: # 1
i = 0
while i < _msg_xml.get_attribute_count() and _msg_xml.get_attribute_name(i) != "name":
i += 1
if i < _msg_xml.get_attribute_count():
name = _msg_xml.get_attribute_value(i)
#print("NODE_ELEMENT level:" + str(level) + " index:" + str(index) + " name:" + name)
if not _msg_xml.is_empty():
dico[str(index)+":"+name] = load_node(_msg_xml, level+1)
else:
dico[str(index)+":"+name] = {}
index += 1
XMLParser.NODE_ELEMENT_END: # 2
# print("NODE_ELEMENT_END")
# level -= 1
return dico
XMLParser.NODE_TEXT: # 3
#i = 0
#while i < _msg_xml.get_attribute_count() and _msg_xml.get_attribute_name(i) != "name":
# i += 1
#if i < _msg_xml.get_attribute_count():
# name = _msg_xml.get_attribute_value(i)
# print("NODE_TEXT level:" + str(level) + " name:" + name)
pass
XMLParser.NODE_COMMENT: # 4
# print("NODE_COMMENT")
pass
XMLParser.NODE_CDATA: # 5
# print("NODE_CDATA")
pass
XMLParser.NODE_UNKNOWN: # 6
# print("NODE_UNKNOWN")
pass
_:
# print("NODE_XXXXXXX")
pass
ret = _msg_xml.read()
return dico
func read_all_node(): func read_all_node():
var _msg_xml = XMLParser.new() var _msg_xml = XMLParser.new()
_msg_xml.open("res://assets/Definition/msg.xml") _msg_xml.open("res://assets/Definition/msg.xml")
var i
_msg_xml.seek(0) _msg_xml.seek(0)
var ret = _msg_xml.read() var dico = load_node(_msg_xml, 0)
var branch = "" var ref = ReferentialMessage.new()
var leaf = "" #print(dico)
var ibranch = 0 ref.read_referential(dico)
var ileaf = 0 ref.show()
while ret == OK: #print("---")
#print("Node: Name:" + _msg_xml.get_node_name() + ", Type:" + str(_msg_xml.get_node_type()) + ", Data:" + str(_msg_xml.get_node_data()) + ", attribut count:" + str(_msg_xml.get_attribute_count()) )
#i = 0
#while i < _msg_xml.get_attribute_count():
# print(" -- Attribut Name:" + _msg_xml.get_attribute_name(i) + " Value:" + _msg_xml.get_attribute_value(i))
# i += 1
if _msg_xml.get_node_type() != XMLParser.NODE_ELEMENT:
ret = _msg_xml.read()
continue
match _msg_xml.get_node_name():
"branch":
i = 0
while i < _msg_xml.get_attribute_count() and _msg_xml.get_attribute_name(i) != "name":
i += 1
if i < _msg_xml.get_attribute_count():
branch = _msg_xml.get_attribute_value(i)
#print(branch + " " + str(_msg_xml.get_node_type()))
_msg_data[branch] = {"leaf": {}, "pos": ibranch}
ibranch += 1
ileaf = 0
"leaf":
i = 0
while i < _msg_xml.get_attribute_count() and _msg_xml.get_attribute_name(i) != "name":
i += 1
if i < _msg_xml.get_attribute_count():
leaf = _msg_xml.get_attribute_value(i)
#print(branch + ":" + leaf + str(_msg_xml.get_node_type()))
_msg_data[branch]["leaf"][leaf] = ileaf
ileaf += 1
ret = _msg_xml.read()
#var networkConnexion = NetworkConnexion.new()
if ProjectSettings.get_setting("khaganat/debug_mode"):
#print("Branch:" + str(_msg_data.size()))
var sizebranch = _msg_data.size()
#NetworkConnexion.get_master_message_description_node().->set_name("Master")
for key in _msg_data:
var sizeleaf = _msg_data[key]["leaf"].size()
print(" " + key + " -> " + str(_msg_data[key]["pos"]) + "/" + str(sizebranch))
for leaf in _msg_data[key]["leaf"]:
var opt = str(_msg_data[key]["pos"]) + "/" + str(sizebranch) + " : " + str(_msg_data[key]["leaf"][leaf]) + "/" + str(sizeleaf)
print(" " + key + ":" + leaf + " -> " + opt)
# Called when the node enters the scene tree for the first time. # Called when the node enters the scene tree for the first time.
func _ready(): func _ready():

View file

@ -18,6 +18,7 @@
extends Control extends Control
var _networkconnection = NetworkConnection.new() var _networkconnection = NetworkConnection.new()
var _referentialmessage = ReferentialMessage.new()
func _ready(): func _ready():
pass pass
@ -51,3 +52,4 @@ func _exit_tree():
print("[net_low_level] End") print("[net_low_level] End")
disconnect_server() disconnect_server()
_networkconnection.terminate_network_connection() _networkconnection.terminate_network_connection()
_referentialmessage.clear_session()

View file

@ -20,7 +20,7 @@ Build :
*/ */
#include "bitstream.h" #include "modules/bitstream/bitstream.h"
// TODO - check if on godot we have a function or variable to get if processor is little_endian or not // TODO - check if on godot we have a function or variable to get if processor is little_endian or not
bool little_endian = false; bool little_endian = false;
@ -337,13 +337,20 @@ void BitStream::put_data(PoolByteArray value)
} }
void BitStream::put_bitstream(Ref<BitStream> value) void BitStream::copy_ref_bitstream(Ref<BitStream> value)
{ {
this->_data = value->_data; //*value.ptr(); this->_data = value->_data; //*value.ptr();
this->_pos = value->_pos; // ->size() * 8; this->_pos = value->_pos; // ->size() * 8;
this->_read = value->_read; this->_read = value->_read;
} }
void BitStream::copy_bitstream(BitStream & value)
{
this->_data = value._data; //*value.ptr();
this->_pos = value._pos; // ->size() * 8;
this->_read = value._read;
}
uint32_t BitStream::get_serial(uint32_t nbits) uint32_t BitStream::get_serial(uint32_t nbits)
{ {
uint32_t value; uint32_t value;
@ -461,4 +468,4 @@ PoolByteArray BitStream::get_array_uint8(uint32_t length)
--length; --length;
} }
return ret; return ret;
} }

View file

@ -65,7 +65,8 @@ public:
PoolByteArray get_data(); PoolByteArray get_data();
void put_data(PoolByteArray value); void put_data(PoolByteArray value);
void put_bitstream(Ref<BitStream> value); void copy_ref_bitstream(Ref<BitStream> value);
void copy_bitstream(BitStream & value);
uint32_t get_serial(uint32_t nbits); uint32_t get_serial(uint32_t nbits);
bool get_bool(); bool get_bool();

View file

@ -90,6 +90,5 @@ MessageDescriptionNode & NetworkConnection::get_master_message_description_node(
*/ */
void NetworkConnection::terminate_network_connection() void NetworkConnection::terminate_network_connection()
{ {
if ( NetworkConnectionCore::is_active() ) NetworkConnectionCore::terminate_connexion();
NetworkConnectionCore::get_singleton()->terminate_connexion();
} }

View file

@ -92,6 +92,7 @@ void NetworkConnectionCore::open_network()
OS::get_singleton()->print("Connect to %s:%ld\n", this->_host.ascii().get_data(), this->_port); OS::get_singleton()->print("Connect to %s:%ld\n", this->_host.ascii().get_data(), this->_port);
this->_socketUDP->set_dest_address(this->_host, this->_port); this->_socketUDP->set_dest_address(this->_host, this->_port);
} }
void NetworkConnectionCore::close_network() void NetworkConnectionCore::close_network()
{ {
this->_socketUDP->close(); this->_socketUDP->close();
@ -140,48 +141,15 @@ void NetworkConnectionCore::connect_to_server()
void NetworkConnectionCore::send_system_quit() void NetworkConnectionCore::send_system_quit()
{ {
this->_state_connexion->send_system_quit(); this->_state_connexion->send_system_quit();
/*
// TODO - check why we send quit_id
if ( this->_state != STATE::Connected && this->_state != STATE::ForceSynchronize )
return;
OS::get_singleton()->print("[%s:%d] send quit to server\n", __FILE__, __LINE__);
BitStream msgout;
msgout.put_uint32(this->_current_received_number);
msgout.put_bool(true);
msgout.put_uint8(CLFECOMMON::SYSTEM_QUIT_CODE);
msgout.put_sint32(this->_quit_id);
if ( this->_socketUDP->put_packet_buffer(msgout.get_data()) != Error::OK )
{
ERR_PRINT("Error to send disconnect");
}
//this->_state = STATE::Quit;
*/
} }
/* /*
* Quit * Disconnect
*/ */
void NetworkConnectionCore::send_system_disconnect() void NetworkConnectionCore::send_system_disconnect()
{ {
this->_state_connexion->send_system_disconnect(); this->_state_connexion->send_system_disconnect();
/*
if ( this->_state != STATE::Connected && this->_state != STATE::ForceSynchronize )
return;
OS::get_singleton()->print("[%s:%d] send disconnect to server\n", __FILE__, __LINE__);
BitStream msgout;
msgout.put_uint32(this->_current_received_number);
msgout.put_bool(true);
msgout.put_uint8(CLFECOMMON::SYSTEM_DISCONNECTION_CODE);
if ( this->_socketUDP->put_packet_buffer(msgout.get_data()) != Error::OK )
{
ERR_PRINT("Error to send disconnect");
}
this->_socketUDP->close();
this->_state = STATE::Disconnect;
*/
} }
/* /*
@ -194,363 +162,6 @@ void NetworkConnectionCore::disconnect_server()
send_system_disconnect(); send_system_disconnect();
} }
/*
* Synchronize
*/
/*
void NetworkConnectionCore::send_system_ack_sync()
{
this->_state_connexion->send_system_ack_sync();
// khanat-opennel-code/code/ryzom/server/src/frontend_service/fe_receive_sub.cpp:1121 void CFeReceiveSub::handleReceivedMsg( CClientHost *clienthost )
OS::get_singleton()->print("[%s:%d] Send system ACK sync\n", __FILE__, __LINE__);
if (this->_state != STATE::Connected && this->_state != STATE::Synchronize)
return;
OS::get_singleton()->print("[%s:%d] Send system ACK probe\n", __FILE__, __LINE__);
OS::get_singleton()->print("[%s:%d] send system ACK Sync to server\n", __FILE__, __LINE__);
Ref<BitStream> msgout;
msgout.instance();
msgout->put_uint32(this->_current_received_number);
msgout->put_bool(true);
msgout->put_uint8(CLFECOMMON::SYSTEM_ACK_SYNC_CODE);
msgout->put_sint32(this->_last_received_number);
msgout->put_sint32(this->_last_ack_in_long_ack);
this->_long_ack_bit_field.write_serial(msgout);
msgout->put_sint32(this->_latest_sync);
if (this->_socketUDP->put_packet_buffer(msgout->get_data()) != Error::OK)
{
ERR_PRINT("Error to send disconnect");
return;
}
msgout.unref();
this->_state = STATE::Connected;
}
*/
void NetworkConnectionCore::receive_system_sync(Ref<BitStream> msgin)
{
/*
int i;
bool valide = true;
//DEBUG_PRINT("SYSTEM_SYNC_CODE");
uint32_t synchronize = msgin->get_uint32();
int64_t stime = msgin->get_sint64();
uint32_t latestsync = msgin->get_uint32();
PoolByteArray msg_xml = msgin->get_array_uint8(16);
PoolByteArray database_xml = msgin->get_array_uint8(16);
OS::get_singleton()->print("[%s:%d] SYSTEM_SYNC_CODE synchronize:%u, stime:%ld, latestsync:%u\n", __FILE__, __LINE__, synchronize, stime, latestsync);
if ( msg_xml.size() != this->_checksum_msg_xml.size() )
{
valide = false;
ERR_PRINTS("MSG XML is incorrect (server:" + itos(msg_xml.size()) +", client:" + itos(this->_checksum_msg_xml.size()) + ")");
}
else
{
for(i=0; i<msg_xml.size(); ++i)
{
if ( (int) msg_xml[i] != (int) this->_checksum_msg_xml[i] )
{
valide = false;
ERR_PRINTS("MSG XML is incorrect (pos:" + itos(i) +")");
}
}
}
if ( valide == true )
{
OS::get_singleton()->print("MSG XML is correct\n");
this->_latest_sync = latestsync;
this->_synchronize = synchronize;
this->_current_server_tick = this->_synchronize + this->_current_received_number + 2;
this->_current_client_tick = this->_current_server_tick + (LCT + this->_ms_per_tick) / this->_ms_per_tick;
this->_current_client_time = this->_update_time - (LCT + this->_ms_per_tick);
this->_state = STATE::Synchronize;
}
else
ERR_PRINTS("MSG.XML is wrong");
*/
}
/*
* Probe
*/
void NetworkConnectionCore::receive_system_probe(Ref<BitStream> msgin)
{
/*
OS::get_singleton()->print("[%s:%d] SYSTEM_PROBE_CODE size:%d\n", __FILE__, __LINE__, this->_latest_probes.size());
this->_latest_probes.append(msgin->get_sint32());
*/
}
void NetworkConnectionCore::send_system_ack_probe()
{
/*
OS::get_singleton()->print("[%s:%d] Send system ACK probe\n", __FILE__, __LINE__);
// khanat-opennel-code/code/ryzom/server/src/frontend_service/fe_receive_sub.cpp:1121 void CFeReceiveSub::handleReceivedMsg( CClientHost *clienthost )
if (this->_state != STATE::Connected && this->_state != STATE::ForceSynchronize)
return;
OS::get_singleton()->print("[%s:%d] Send system ACK probe\n", __FILE__, __LINE__);
int max = this->_latest_probes.size();
if (max == 0 )
return;
if (this->_state == STATE::ForceSynchronize && max < 5)
return;
OS::get_singleton()->print("[%s:%d] send system ACK PROBE to server\n", __FILE__, __LINE__);
BitStream msgout;
msgout.put_uint32(this->_current_received_number);
msgout.put_bool(true);
msgout.put_uint8(CLFECOMMON::SYSTEM_ACK_PROBE_CODE);
msgout.put_sint32(max);
for(int i=0; i < max ; ++i )
{
int data = this->_latest_probes[i];
msgout.put_sint32(data);
}
if (this->_socketUDP->put_packet_buffer(msgout.get_data()) != Error::OK)
{
ERR_PRINT("Error to send disconnect");
return;
}
this->_latest_probes.clear();
if (this->_state == STATE::ForceSynchronize && max >= 5)
{
// We have send ACK, so now we clean all queue and received all message to synchronize
this->_queue.clear();
this->_state = STATE::Connected;
}
*/
}
/*
*
*/
void NetworkConnectionCore::wait_resynchronize(uint32_t current_received_number, Ref<BitStream> msgin)
{
/*
bool system_mode;
this->_current_received_number = current_received_number;
system_mode = msgin->get_bool();
if ( system_mode == true )
{
int message = msgin->get_uint8();
switch (message)
{
case CLFECOMMON::SYSTEM_LOGIN_CODE:
OS::get_singleton()->print("SYSTEM_LOGIN_CODE\n");
break;
case CLFECOMMON::SYSTEM_SYNC_CODE:
OS::get_singleton()->print("SYSTEM_SYNC_CODE\n");
break;
case CLFECOMMON::SYSTEM_STALLED_CODE:
OS::get_singleton()->print("SYSTEM_STALLED_CODE\n");
break;
case CLFECOMMON::SYSTEM_SERVER_DOWN_CODE:
OS::get_singleton()->print("SYSTEM_SERVER_DOWN_CODE\n");
break;
case CLFECOMMON::SYSTEM_PROBE_CODE:
this->receive_system_probe(msgin);
break;
default:
ERR_PRINTS("Received unknown message [" + itos(message) + "]");
break;
}
}
this->_last_received_number = current_received_number;
*/
}
/*
*
*/
void NetworkConnectionCore::decode_system_message(Ref<BitStream> msgin)
{
/*
int message = msgin->get_uint8();
switch (message)
{
case CLFECOMMON::SYSTEM_LOGIN_CODE:
//DEBUG_PRINT("SYSTEM_LOGIN_CODE");
OS::get_singleton()->print("[%s:%d] SYSTEM_LOGIN_CODE\n", __FILE__, __LINE__);
break;
case CLFECOMMON::SYSTEM_SYNC_CODE:
this->receive_system_sync(msgin);
break;
case CLFECOMMON::SYSTEM_STALLED_CODE:
//DEBUG_PRINT("SYSTEM_STALLED_CODE");
OS::get_singleton()->print("[%s:%d] SYSTEM_STALLED_CODE\n", __FILE__, __LINE__);
break;
case CLFECOMMON::SYSTEM_SERVER_DOWN_CODE:
OS::get_singleton()->print("[%s:%d] SYSTEM_SERVER_DOWN_CODE\n", __FILE__, __LINE__);
break;
case CLFECOMMON::SYSTEM_PROBE_CODE:
this->receive_system_probe(msgin);
break;
default:
ERR_PRINTS("Received unknown message [" + itos(message) + "]");
break;
}
*/
}
void NetworkConnectionCore::decode_normal_message(Ref<BitStream> msgin)
{
OS::get_singleton()->print("[%s:%d] Decode normal message\n", __FILE__, __LINE__);
}
/*
*
*/
void NetworkConnectionCore::analyze_message_received(uint32_t current_received_number, Ref<BitStream> msgin)
{
/*
bool system_mode;
bool ackBool = false;
int ackBit = 0;
uint32_t i;
OS::get_singleton()->print("[%s:%d] analyze_message_received state:%d\n", __FILE__, __LINE__, this->_state);
this->_current_received_number = current_received_number;
system_mode = msgin->get_bool();
if ( system_mode == true )
{
OS::get_singleton()->print("Received system message\n");
if (this->_current_received_number == this->_last_received_number + 1)
{
OS::get_singleton()->print("Received message\n");
}
else if (this->_current_received_number < this->_last_received_number + 1)
{
OS::get_singleton()->print("Received old message\n");
return;
}
else if (this->_current_received_number > this->_last_received_number + 1)
{
OS::get_singleton()->print("Received message in future (lost some message)\n");
}
}
else
{
OS::get_singleton()->print("Received normal message\n");
}
if ( system_mode != true )
{
ackBool = true;
ackBit = 1;
}
if ( current_received_number - this->_last_received_number < 32 )
{
this->_ack_bit_mask <<= current_received_number - this->_last_received_number;
this->_ack_bit_mask |= this->_last_ack_bit << (current_received_number - this->_last_received_number - 1);
}
else if (((current_received_number - this->_last_received_number) == 32) && (this->_last_ack_bit != 0))
this->_ack_bit_mask = 0x80000000;
else
this->_ack_bit_mask = 0x00000000;
this->_last_ack_bit = ackBit;
for(i=this->_last_received_number + 1 ;i < _current_received_number; ++i)
this->_long_ack_bit_field.clear_bit(i & (NUM_BITS_IN_LONG_ACK -1) );
OS::get_singleton()->print("long_ack_bit_field.put : %u\n", current_received_number & (NUM_BITS_IN_LONG_ACK-1));
this->_long_ack_bit_field.write(current_received_number & (NUM_BITS_IN_LONG_ACK-1), ackBool);
// TODO - what's action when we have rotate onthis number (max -> 0)
if( this->_last_received_number > 0x08000000 )
{
if(this->_last_ack_in_long_ack <= (this->_last_received_number - NUM_BITS_IN_LONG_ACK))
this->_last_ack_in_long_ack = this->_last_received_number - NUM_BITS_IN_LONG_ACK + 1;
this->_last_received_number = current_received_number;
}
else
{
if(this->_last_ack_in_long_ack - 0x80000000 <= (this->_last_received_number - NUM_BITS_IN_LONG_ACK - 0x80000000))
this->_last_ack_in_long_ack = this->_last_received_number - NUM_BITS_IN_LONG_ACK + 1;
this->_last_received_number = current_received_number;
}
if ( system_mode == true )
this->decode_system_message(msgin);
else
this->decode_normal_message(msgin);
*/
}
void NetworkConnectionCore::store_message_received(PoolByteArray msgbytes)
{
/*
Ref<BitStream> msgin;
msgin.instance();
msgin->put_data(msgbytes);
uint32_t current_received_number = msgin->get_uint32();
//msgin.put_data(msgbytes);
//uint32_t current_received_number = msgin.get_uint32();
OS::get_singleton()->print("[%s:%d] store message (%d)\n", __FILE__, __LINE__, (int)current_received_number);
SHOW_USAGE_MEMORY
show_memory_usage();
Ref<BitStreamField> msg;
msg.instance();
msg->put_id(current_received_number);
msg->put_msgin(msgin);
int index = this->_queue.put_bitstreamfield(msg);
msg.unref();
/// TODO - check if max int execeded current_received_number < 1000 this->_last_received_number > 0x80000000
if ( this->_state == STATE::ForceSynchronize )
{
// We have detected a problem of synchro, we wait message ack probe and after server launch a re-sync
//wait_resynchronize(current_received_number, msgin);
this->_queue.erase_index(index);
}
else if ( current_received_number - this->_last_received_number <= 0 ) // Received old message
{
OS::get_singleton()->print("[%s:%d] current_received_number:%d / queue size:%d\n", __FILE__, __LINE__, current_received_number, this->_queue.length());
this->_queue.erase_index(index);
return;
}
else if ( this->_last_received_number + 1 == current_received_number ) // Received next message
{
OS::get_singleton()->print("[%s:%d] current_received_number:%u / queue size:%d\n", __FILE__, __LINE__, current_received_number, this->_queue.length());
//analyze_message_received(current_received_number, msgin);
this->_queue.erase_index(index);
}
else // Received new message (but missing some message between) -> go to queue and cross finger to received the next message (for _last_received_number)
{
OS::get_singleton()->print("[%s:%d] current_received_number:%d / queue size:%d\n", __FILE__, __LINE__, current_received_number, this->_queue.length());
if (this->_queue.length() >= SIZE_QUEUE_MESSAGE)
{
ERR_PRINT("Network queue is full / wait re-synchronize");
this->_state = STATE::ForceSynchronize ;
return;
}
}
*/
}
void NetworkConnectionCore::send_message()
{
/*
if (this->_latest_probes.size() > 0)
send_system_ack_probe();
else if (this->_state == STATE::Synchronize)
send_system_ack_sync();
*/
}
void NetworkConnectionCore::process(int delta) void NetworkConnectionCore::process(int delta)
{ {
// this->_state_connexion->process(delta); // this->_state_connexion->process(delta);
@ -598,21 +209,9 @@ bool NetworkConnectionCore::is_active()
void NetworkConnectionCore::terminate_connexion() void NetworkConnectionCore::terminate_connexion()
{ {
OS::get_singleton()->print("[%s:%d] Terminate network connexion .\n", __FILE__, __LINE__);
if ( NetworkConnectionCore::singleton == nullptr ) if ( NetworkConnectionCore::singleton == nullptr )
return; return;
OS::get_singleton()->print("[%s:%d] Terminate network connexion ..\n", __FILE__, __LINE__); OS::get_singleton()->print("[%s:%d] Terminate network connexion ..\n", __FILE__, __LINE__);
OS::get_singleton()->print("[%s:%d] Terminate network connexion ...\n", __FILE__, __LINE__);
delete NetworkConnectionCore::singleton; delete NetworkConnectionCore::singleton;
if ( NetworkConnectionCore::singleton != nullptr ) NetworkConnectionCore::singleton = nullptr;
OS::get_singleton()->print("[%s:%d] Terminate network connexion ?\n", __FILE__, __LINE__);
OS::get_singleton()->print("[%s:%d] Terminate network connexion ....\n", __FILE__, __LINE__);
} }
/*
MessageDescriptionNode & NetworkConnectionCore::get_master_message_description_node()
{
return this->_message_description_node;
}
*/

View file

@ -27,8 +27,9 @@
#include "modules/bitstreamqueue/bitstreamqueue.h" #include "modules/bitstreamqueue/bitstreamqueue.h"
#include "state_connexion.h" #include "state_connexion.h"
#include "network_data.h" #include "network_data.h"
#include "modules/referentialmessage/referentialmessage.h"
#define MAX_LOOP_READ_BY_STEP 10 #define MAX_LOOP_READ_BY_STEP 5
#define LCT 100 #define LCT 100
@ -60,8 +61,6 @@ protected:
NetworkData _network_data; NetworkData _network_data;
//MessageDescriptionNode _message_description_node;
void open_network(); void open_network();
void close_network(); void close_network();
public: public:
@ -88,22 +87,10 @@ public:
void send_system_quit(); void send_system_quit();
void disconnect_server(); void disconnect_server();
void send_system_ack_probe();
void receive_system_probe(Ref<BitStream> msgin);
void send_system_ack_sync();
void receive_system_sync(Ref<BitStream> msgin);
void decode_system_message(Ref<BitStream> msgin);
void decode_normal_message(Ref<BitStream> msgin);
void wait_resynchronize(uint32_t current_received_number, Ref<BitStream> msgin);
void analyze_message_received(uint32_t current_received_number, Ref<BitStream> msgin);
void store_message_received(PoolByteArray msgbytes);
void send_message();
void process(int delta); void process(int delta);
bool connected(); bool connected();
static bool is_active(); static bool is_active();
void terminate_connexion(); static void terminate_connexion();
//MessageDescriptionNode & get_master_message_description_node(); //MessageDescriptionNode & get_master_message_description_node();
}; };

View file

@ -26,7 +26,7 @@
#include "modules/bitset/bitset.h" #include "modules/bitset/bitset.h"
#include "core/ustring.h" #include "core/ustring.h"
#define MAX_LOOP_READ_BY_STEP 10 //define MAX_LOOP_READ_BY_STEP 10
#define NUM_BITS_IN_LONG_ACK 512 #define NUM_BITS_IN_LONG_ACK 512
class NetworkData class NetworkData

View file

@ -22,6 +22,13 @@
#include "state_connexion.h" #include "state_connexion.h"
#include "network_connection_core.h" #include "network_connection_core.h"
// We need managed when number 'uint32_t' exceed the capacity (32bits => 4294967296)
// So, we split in two group.
// < 0...1073741824 > < 1073741825 ... 3221225472 > < 3221225472 ... 4294967295 >
// Group 1 : < 0...1073741824 > + < 3221225472 ... 4294967295 > => number value : 2147483648
// Group 2 : < 1073741825 ... 3221225472 > => number value : 2147483648
/* /*
* StateConnectionBase * StateConnectionBase
*/ */
@ -365,6 +372,14 @@ void StateConnectionConnected::receive_message(int index)
Ref<BitStreamField> field = this->_network->_queue.get_msg(index); Ref<BitStreamField> field = this->_network->_queue.get_msg(index);
uint32_t current_received_number = field->get_id(); uint32_t current_received_number = field->get_id();
if (current_received_number - this->_data->_current_received_number != 1)
{
if(this->_network->_queue.length() >= MAX_SIZE_BIT_STREAM_QUEUE)
this->_network->_state_connexion = & this->_network->_state_synchronize;
return;
}
this->_data->_current_received_number = current_received_number; this->_data->_current_received_number = current_received_number;
Ref<BitStream> msgin = field->get_msgin(); Ref<BitStream> msgin = field->get_msgin();
@ -403,6 +418,9 @@ void StateConnectionConnected::receive_message(int index)
OS::get_singleton()->print("[%s:%d] application message (%d) [%d]\n", __FILE__, __LINE__, (int)current_received_number, this->_network->_queue.length()); OS::get_singleton()->print("[%s:%d] application message (%d) [%d]\n", __FILE__, __LINE__, (int)current_received_number, this->_network->_queue.length());
} }
this->_network->_queue.erase_index(index); this->_network->_queue.erase_index(index);
// Check in buffer if we have next
if ( this->_network->_queue.is_index(index + 1) )
this->receive_message(index + 1);
} }
void StateConnectionConnected::send_message() void StateConnectionConnected::send_message()

View file

@ -27,7 +27,8 @@
#include "modules/bitstreamqueue/bitstreamqueue.h" #include "modules/bitstreamqueue/bitstreamqueue.h"
#include "network_data.h" #include "network_data.h"
#define NUM_BITS_IN_LONG_ACK 512 #define MAX_SIZE_BIT_STREAM_QUEUE 10
#define NUM_BITS_IN_LONG_ACK 512
enum STATE { enum STATE {
NotInitialised = 0, NotInitialised = 0,

View file

@ -0,0 +1,5 @@
# SCsub
Import('env')
env.add_source_files(env.modules_sources, "*.cpp") # Add all cpp files to the build

View file

@ -0,0 +1,15 @@
# config.py
def can_build(env, platform):
return True
def configure(env):
pass
def get_doc_classes():
return [
"ReferentialMessage",
]
def get_doc_path():
return "doc_classes"

View file

@ -0,0 +1,46 @@
/*
ReferentialMessage : Class to store referential to decode message
Copyright (C) 2019 AleaJactaEst
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "referentialmessage.h"
#include "core/os/os.h"
void ReferentialMessage::_bind_methods()
{
ClassDB::bind_method(D_METHOD("read_referential", "dictionary_message"), &ReferentialMessage::read_referential);
ClassDB::bind_method(D_METHOD("show"), &ReferentialMessage::show);
ClassDB::bind_method(D_METHOD("clear_session"), &ReferentialMessage::clear_session);
}
void ReferentialMessage::read_referential(Dictionary dictionary_message)
{
ReferentialMessageCore::clear_session();
ReferentialMessageCore::get_singleton()->read_referential(dictionary_message);
}
void ReferentialMessage::show()
{
ReferentialMessageCore::get_singleton()->show();
}
void ReferentialMessage::clear_session()
{
ReferentialMessageCore::clear_session();
}

View file

@ -0,0 +1,45 @@
/*
Header ReferentialMessage : Class to store referential to decode message
Copyright (C) 2019 AleaJactaEst
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef REFERENTIAL_MESSAGE_H
#define REFERENTIAL_MESSAGE_H
#include "core/reference.h"
//#include "core/dictionary.h"
//#include "modules/bitstream/bitstream.h"
#include "modules/referentialmessage/referentialmessagecore.h"
class ReferentialMessage : public Reference {
GDCLASS(ReferentialMessage, Reference)
protected:
static void _bind_methods();
public:
ReferentialMessage() {}
~ReferentialMessage() {}
/* _init must exist as it is called by Godot */
void _init() {};
void read_referential(Dictionary dictionary_message);
void show();
void clear_session();
};
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,442 @@
/*
Header ReferentialMessageCore : Class to store referential to decode message
Copyright (C) 2019 AleaJactaEst
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef REFERENTIAL_MESSAGE_CORE_H
#define REFERENTIAL_MESSAGE_CORE_H
#include "core/reference.h"
#include "core/dictionary.h"
#include "modules/bitstream/bitstream.h"
inline uint32_t getPowerOf2(uint32_t v)
{
// See code : khanat-opennel-code/code/nel/src/misc/common.cpp
uint32_t res = 1;
uint32_t ret = 0;
uint32_t limit = 8*sizeof(uint32_t);
while(res < v && res < limit)
{
ret ++;
res <<= 1; // res *= 2;
}
return ret;
}
class ElementReferential : public Reference
{
GDCLASS(ElementReferential, Reference)
private:
uint32_t _id;
uint32_t _power2;
Vector<Ref<ElementReferential>> _children;
public:
ElementReferential() {_id=0; _power2=0;}
~ElementReferential() {_children.clear();}
void set_id(uint32_t id) {_id=id;}
void set_size(uint32_t size) {_children.resize(size); _power2=getPowerOf2(size);}
int get_size() { return _children.size();}
Ref<ElementReferential> add_child(uint32_t id, uint32_t pos) { Ref<ElementReferential> tmp; tmp.instance(); tmp->_id = id; _children.set(pos, tmp); tmp.unref(); return _children[pos]; }
void show(int level=0, int pos=0);
};
class ReferentialMessageCore : public Reference
{
GDCLASS(ReferentialMessageCore, Reference)
protected:
static void _bind_methods();
public:
enum Command {
TARGET_PARTY,
TARGET_INVENTORY,
TARGET_FOLLOW,
TARGET_NO_FOLLOW,
CONNECTION_USER_CHAR,
CONNECTION_NO_USER_CHAR,
CONNECTION_USER_CHARS,
CONNECTION_CREATE_CHAR,
CONNECTION_SELECT_CHAR,
CONNECTION_DELETE_CHAR,
CONNECTION_RENAME_CHAR,
CONNECTION_ENTER,
CONNECTION_READY,
CONNECTION_TIME_DATE_SYNCHRO,
CONNECTION_ASK_NAME,
CONNECTION_VALID_NAME,
CONNECTION_CREATE_CHAR_ERROR,
CONNECTION_RECONNECT,
CONNECTION_SERVER_RECONNECT_OK,
CONNECTION_SHARD_ID,
CONNECTION_SERVER_QUIT_OK,
CONNECTION_SERVER_QUIT_ABORT,
CONNECTION_CLIENT_QUIT_REQUEST,
CONNECTION_MAIL_AVAILABLE,
CONNECTION_GUILD_MESSAGE_AVAILABLE,
CONNECTION_PERMANENT_BAN,
CONNECTION_UNBAN,
CONNECTION_FAR_TP,
CONNECTION_RET_MAINLAND,
DB_UPD_PLR,
DB_UPD_INV,
DB_INIT_PLR,
DB_INIT_INV,
DB_GROUP_UPDATE_BANK,
DB_GROUP_INIT_BANK,
DB_GROUP_RESET_BANK,
POSITION,
HARVEST_DEPOSIT,
HARVEST_CORPSE,
HARVEST_INTERRUPT,
HARVEST_CLOSE_TEMP_INVENTORY,
TRAINING,
JOB_SET_JOB_STATUS,
JOB_SWAP_JOB_STATUS,
CASTING_BEGIN,
CASTING_INTERRUPT,
FABER_OPEN,
FABER_CLOSE,
FABER_EXECUTE,
FABER_SET_NUM_ITEM,
FABER_START_CREATE,
FABER_START_REPAIR,
FABER_START_REFINE,
FABER_SET_MP_QUALITY,
FABER_SET_MP_REFINE,
FABER_SET_TOOL,
FABER_RESET_TOOL,
FABER_INTERRUPT,
COMBAT_ENGAGE,
COMBAT_DISENGAGE,
COMBAT_DEFAULT_ATTACK,
COMBAT_ENGAGE_FAILED,
COMBAT_VALIDATE_MELEE,
COMBAT_PARRY,
COMBAT_DODGE,
COMBAT_PROTECTED_SLOT,
COMBAT_FLYING_ChaScore1_DELTA,
COMBAT_FLYING_TEXT_ISE,
COMBAT_FLYING_TEXT,
STRING_TELL,
STRING_FAR_TELL,
STRING_CHAT,
STRING_CHAT_TEAM,
STRING_ADD_DYN_STR,
STRING_FILTER,
STRING_CHAT_MODE,
STRING_CHAT2,
STRING_TELL2,
STRING_DYN_STRING,
STRING_DYN_STRING_GROUP,
STRING_AFK_TXT,
STUN_STUN,
STUN_WAKE_UP,
SENTENCE_EXECUTE,
SENTENCE_CANCEL,
SENTENCE_CANCEL_CURRENT,
SENTENCE_CANCEL_ALL,
SENTENCE_CLEAR,
SENTENCE_MEMORIZE,
SENTENCE_FORGET,
SENTENCE_EVALUATE,
SENTENCE_ADD_BRICK,
SENTENCE_REMOVE_BRICK,
SENTENCE_START,
SENTENCE_STOP,
TEAM_JOIN,
TEAM_LEAVE,
TEAM_INVITATION,
TEAM_JOIN_PROPOSAL,
TEAM_JOIN_PROPOSAL_DECLINE,
TEAM_KICK,
TEAM_SET_SUCCESSOR,
TEAM_SHARE_OPEN,
TEAM_SHARE_VALID_ITEM,
TEAM_SHARE_INVALID_ITEM,
TEAM_SHARE_VALID,
TEAM_SHARE_INVALID,
TEAM_SHARE_CLOSE,
TEAM_CONTACT_INIT,
TEAM_CONTACT_ADD,
TEAM_CONTACT_DEL,
TEAM_CONTACT_MOVE,
TEAM_CONTACT_CREATE,
TEAM_CONTACT_STATUS,
TEAM_CONTACT_REMOVE,
ITEM_DROP,
ITEM_PICK_UP,
ITEM_PICK_UP_CLOSE,
ITEM_SWAP,
ITEM_ACTIVATE_SHEATH,
ITEM_HARVEST,
ITEM_HARVEST_CLOSE,
ITEM_GIVE,
ITEM_DESTROY,
ITEM_EQUIP,
ITEM_UNEQUIP,
ITEM_TEMP_TO_BAG,
ITEM_ALL_TEMP,
ITEM_NO_TEMP,
ITEM_ENCHANT,
ITEM_OPEN_ROOM_INVENTORY,
ITEM_CLOSE_ROOM_INVENTORY,
ITEM_USE_ITEM,
ITEM_STOP_USE_XP_CAT,
TP_RESPAWN,
TP_BOT,
TP_WANTED,
TP_DEST,
TP_DEST_WITH_SEASON,
TP_ACK,
TP_CORRECT,
DEATH_RESPAWN_POINT,
DEATH_ASK_RESPAWN,
DEATH_RESPAWN,
ANIMALS_BEAST,
ANIMALS_MOUNT_ABORT,
EXCHANGE_INVITATION,
EXCHANGE_CLOSE_INVITATION,
EXCHANGE_PROPOSAL,
EXCHANGE_ACCEPT_INVITATION,
EXCHANGE_DECLINE_INVITATION,
EXCHANGE_VALIDATE,
EXCHANGE_INVALIDATE,
EXCHANGE_END,
EXCHANGE_SEEDS,
EXCHANGE_ADD,
EXCHANGE_REMOVE,
DEBUG_WHERE,
DEBUG_WHO,
DEBUG_REPLY_WHERE,
DEBUG_SERVICES,
DEBUG_CMD,
DEBUG_PING,
DEBUG_COUNTER,
COMMAND_EMOTE,
COMMAND_CUSTOM_EMOTE,
COMMAND_WHERE,
COMMAND_ADMIN,
COMMAND_ADMIN_OFFLINE,
COMMAND_REMOTE_ADMIN,
COMMAND_REMOTE_ADMIN_ANSWER,
COMMAND_SIT,
COMMAND_AFK,
COMMAND_RANDOM,
COMMAND_GUILDMOTD,
MP_EVAL_SET_MP,
MP_EVAL_SET_MP_LEVEL,
MP_EVAL_SET_MARKET,
MP_EVAL_EXECUTE,
BOTCHAT_NEXT_PAGE_ITEM,
BOTCHAT_NEXT_PAGE_MISSION,
BOTCHAT_START_TRADE_ITEM,
BOTCHAT_START_TRADE_TELEPORT,
BOTCHAT_START_TRADE_FACTION,
BOTCHAT_START_TRADE_SKILL,
BOTCHAT_START_TRADE_PACT,
BOTCHAT_START_TRADE_ACTION,
BOTCHAT_BUY,
BOTCHAT_SELL,
BOTCHAT_DESTROY_ITEM,
BOTCHAT_REFRESH_TRADE_LIST,
BOTCHAT_SET_FILTERS,
BOTCHAT_START_CHOOSE_MISSION,
BOTCHAT_START_DYNAMIC_MISSION,
BOTCHAT_CONTINUE_MISSION,
BOTCHAT_VALIDATE_PLAYER_GIFT,
BOTCHAT_PICK_MISSION,
BOTCHAT_DM_CHOICE,
BOTCHAT_DM_ACCEPT,
BOTCHAT_START_NEWS,
BOTCHAT_START_CREATE_GUILD,
BOTCHAT_END,
BOTCHAT_FORCE_END,
BOTCHAT_START_CHOOSE_DUTY,
BOTCHAT_NEXT_PAGE_DUTY,
BOTCHAT_DUTY_APPLY,
BOTCHAT_DUTY_CANCEL_APPLY,
BOTCHAT_START_TRADE_GUILD_OPTIONS,
BOTCHAT_BUY_GUILD_OPTION,
BOTCHAT_START_GUILD_RESEARCH,
BOTCHAT_DESTROY_BUILDING,
BOTCHAT_DYNCHAT_OPEN,
BOTCHAT_DYNCHAT_CLOSE,
BOTCHAT_DYNCHAT_SEND,
JOURNAL_INIT_COMPLETED_MISSIONS,
JOURNAL_UPDATE_COMPLETED_MISSIONS,
JOURNAL_MISSION_ABANDON,
JOURNAL_GROUP_MISSION_ABANDON,
JOURNAL_ADD_COMPASS,
JOURNAL_ADD_COMPASS_BOT,
JOURNAL_REMOVE_COMPASS,
JOURNAL_REMOVE_COMPASS_BOT,
STRING_MANAGER_SET_LANGUAGE,
STRING_MANAGER_PHRASE_SEND,
STRING_MANAGER_STRING_RQ,
STRING_MANAGER_STRING_RESP,
STRING_MANAGER_RELOAD_CACHE,
GUILD_CREATE,
GUILD_ABORT_CREATION,
GUILD_OPEN_GUILD_WINDOW,
GUILD_INVITATION,
GUILD_ACCEPT_INVITATION,
GUILD_REFUSE_INVITATION,
GUILD_JOIN_PROPOSAL,
GUILD_SET_GRADE,
GUILD_SET_LEADER,
GUILD_KICK_MEMBER,
GUILD_TELEPORT,
GUILD_ASCENSOR,
GUILD_FIRST_ASCENSOR_PAGE,
GUILD_NEXT_ASCENSOR_PAGE,
GUILD_LEAVE_ASCENSOR,
GUILD_QUIT,
GUILD_SET_PLAYER_TITLE,
GUILD_UPDATE_PLAYER_TITLE,
GUILD_USE_FEMALE_TITLES,
GUILD_PUT_MONEY,
GUILD_TAKE_MONEY,
GUILD_OPEN_INVENTORY,
GUILD_CLOSE_INVENTORY,
OUTPOST_GIVEUP_OUTPOST,
OUTPOST_SELECT,
OUTPOST_UNSELECT,
OUTPOST_DECLARE_WAR_START,
OUTPOST_DECLARE_WAR_ACK,
OUTPOST_DECLARE_WAR_VALIDATE,
OUTPOST_SET_DEF_PERIOD,
OUTPOST_SET_SQUAD,
OUTPOST_SET_SQUAD_SPAWN,
OUTPOST_INSERT_SQUAD,
OUTPOST_REMOVE_SQUAD,
OUTPOST_SET_SQUAD_CAPITAL,
OUTPOST_CHOOSE_SIDE,
OUTPOST_SIDE_CHOSEN,
OUTPOST_BANISH_PLAYER,
OUTPOST_BANISH_GUILD,
OUTPOST_BUY_BUILDING,
OUTPOST_DESTROY_BUILDING,
PHRASE_DELETE,
PHRASE_LEARN,
PHRASE_MEMORIZE,
PHRASE_FORGET,
PHRASE_EXECUTE,
PHRASE_EXECUTE_CYCLIC,
PHRASE_EXECUTE_FABER,
PHRASE_DOWNLOAD,
PHRASE_BUY,
PHRASE_CONFIRM_BUY,
PHRASE_BUY_SHEET,
PHRASE_CANCEL_LINK,
PHRASE_CANCEL_TOP,
PHRASE_CANCEL_ALL,
PHRASE_CRISTALIZE,
PHRASE_EXEC_CYCLIC_ACK,
PHRASE_EXEC_NEXT_ACK,
ITEM_INFO_GET,
ITEM_INFO_SET,
ITEM_INFO_REFRESH_VERSION,
MISSION_PREREQ_GET,
MISSION_PREREQ_SET,
MISSION_ENTER_CRITICAL,
MISSION_ASK_ENTER_CRITICAL,
MISSION_CLOSE_ENTER_CRITICAL,
MISSION_WAKE,
MISSION_GROUP_WAKE,
DUEL_ASK,
DUEL_ACCEPT,
DUEL_REFUSE,
DUEL_ABANDON,
DUEL_INVITATION,
DUEL_CANCEL_INVITATION,
PVP_CHALLENGE_ASK,
PVP_CHALLENGE_ACCEPT,
PVP_CHALLENGE_REFUSE,
PVP_CHALLENGE_ABANDON,
PVP_CHALLENGE_INVITATION,
PVP_CHALLENGE_CANCEL_INVITATION,
PVP_PVP_TAG,
PVP_SET_NEUTRAL_ALLEGIANCE,
PVP_SET_NEUTRAL_ALLEGIANCE_GUILD,
PVP_FACTION_PUSH_FACTION_WAR,
PVP_FACTION_POP_FACTION_WAR,
PVP_FACTION_FACTION_WARS,
ENCYCLOPEDIA_UPDATE,
ENCYCLOPEDIA_INIT,
USER_BARS,
USER_POPUP,
EVENT_SET_ITEM_CUSTOM_TEXT,
EVENT_DUMMY,
TOTEM_BUILD,
TOTEM_DUMMY,
MODULE_GATEWAY_FEOPEN,
MODULE_GATEWAY_GATEWAY_MSG,
MODULE_GATEWAY_FECLOSE,
SEASON_SET,
SEASON_DUMMY,
DM_GIFT_BEGIN,
DM_GIFT_VALIDATE,
RING_MISSION_MISSION_RING_SELECT,
RING_MISSION_DSS_DOWN,
NPC_ICON_GET_DESC,
NPC_ICON_SET_DESC,
NPC_ICON_SVR_EVENT_MIS_AVL,
NPC_ICON_SET_TIMER,
__LAST_ELEMENT
};
class ElementHead
{
private:
uint32_t _size;
uint32_t _pos;
String _name;
public:
ElementHead() {}
~ElementHead() {}
void set_size(uint32_t size){_size = size;}
void set_pos(uint32_t pos){_pos = pos;}
void set_name(String name){_name = name;}
void create(uint32_t pos, uint32_t size,String name) {set_pos(pos);set_size(size);set_name(name);}
uint32_t get_size() {return _size;}
uint32_t get_pos() {return _pos;}
String get_name() {return _name;}
};
private:
static ReferentialMessageCore *singleton;
BitStream _encoder[Command::__LAST_ELEMENT];
Ref<ElementReferential> _decoder;
int get_command(String name);
void read_referential_step(Dictionary step, Vector<ElementHead> head, Ref<ElementReferential> root);
public:
static ReferentialMessageCore * get_singleton();
ReferentialMessageCore() {_decoder.instance();}
~ReferentialMessageCore() {_decoder.unref();}
void read_referential(Dictionary dictionary_message);
void show();
static void clear_session();
};
VARIANT_ENUM_CAST(ReferentialMessageCore::Command);
#endif

View file

@ -0,0 +1,15 @@
/* register_types.cpp */
#include "register_types.h"
#include "core/class_db.h"
#include "referentialmessage.h"
void register_referentialmessage_types() {
ClassDB::register_class<ReferentialMessage>();
ClassDB::register_class<ReferentialMessageCore>();
}
void unregister_referentialmessage_types() {
// Nothing to do here in this example.
}

View file

@ -0,0 +1,5 @@
/* register_types.h */
void register_referentialmessage_types();
void unregister_referentialmessage_types();
/* yes, the word in the middle must be the same as the module folder name */