update network part

This commit is contained in:
AleaJactaEst 2020-03-03 22:45:30 +01:00
parent 74149c46ac
commit dca2fb7a9a
22 changed files with 1273 additions and 282 deletions

View file

@ -22,11 +22,11 @@ var _networkconnection = NetworkConnection.new()
func _ready():
pass
func send_system_login(host, port, user_addr, user_key, user_id, lang):
_networkconnection.define_server(host, port)
_networkconnection.define_user(user_addr, user_key, user_id)
_networkconnection.define_lang(lang)
_networkconnection.send_system_login()
#func send_system_login(host, port, user_addr, user_key, user_id, lang):
# _networkconnection.define_server(host, port)
# _networkconnection.define_user(user_addr, user_key, user_id)
# _networkconnection.define_lang(lang)
# _networkconnection.connect_to_server()
func send_system_quit():
_networkconnection.send_system_quit()
@ -38,7 +38,11 @@ func disconnect_server():
_networkconnection.disconnect_server()
func connect_to_server(host, port, user_addr, user_key, user_id, lang):
send_system_login(host, port, user_addr, user_key, user_id, lang)
_networkconnection.define_server(host, port)
_networkconnection.define_user(user_addr, user_key, user_id)
_networkconnection.define_lang(lang)
_networkconnection.connect_to_server()
#send_system_login(host, port, user_addr, user_key, user_id, lang)
func _process(delta):
_networkconnection.process(delta)

View file

@ -18,12 +18,12 @@ func test_init():
assert(res == 0)
bitstreamqueue.clear()
res = bitstreamqueue.get_received_number(0)
res = bitstreamqueue.length()
assert(res == 0)
func test_msg_1():
var bitstreamqueue = BitStreamQueue.new()
var pos
var index
var res
var tmp = PoolByteArray()
tmp.append(0)
@ -32,29 +32,39 @@ func test_msg_1():
tmp.append(3)
tmp.append(2)
res = bitstreamqueue.length()
assert(res == 0)
var data = BitStream.new()
assert(bitstreamqueue.length() == 0)
pos = bitstreamqueue.put_msgbytes(tmp)
data.put_data(tmp)
var id = data.get_uint32()
assert(id == 3)
res = bitstreamqueue.get_received_number(pos)
assert(res == 3)
var bitstreamfield = BitStreamField.new()
bitstreamfield.put_id(id)
bitstreamfield.put_msgin(data)
res = bitstreamqueue.get_msg(pos)
index = bitstreamqueue.put_bitstreamfield(bitstreamfield)
assert(index == 0)
assert(bitstreamqueue.length() == 1)
#res = bitstreamqueue.get_received_number(pos)
#assert(res == 3)
res = bitstreamqueue.get_msg(index)
#print(res.show())
assert(res.show() == "0000000000000000000000000000001100000010")
assert(res.get_msgin().show() == "0000000000000000000000000000001100000010")
res = bitstreamqueue.get_received_number(pos)
assert(res == 3)
#res = bitstreamqueue.get_msg_withid(id)
#assert(res == 3)
res = bitstreamqueue.length()
assert(res == 1)
bitstreamqueue.erase(pos)
bitstreamqueue.erase_index(index)
res = bitstreamqueue.length()
assert(res == 0)
func test_msg_2():
var bitstreamqueue = BitStreamQueue.new()
var pos
var index
var res
var tmp = PoolByteArray()
tmp.append(0)
@ -63,17 +73,151 @@ func test_msg_2():
tmp.append(2)
tmp.append(7)
pos = bitstreamqueue.put_msgbytes(tmp)
res = bitstreamqueue.get_received_number(pos)
assert(res == 2)
var data = BitStream.new()
assert(bitstreamqueue.length() == 0)
res = bitstreamqueue.get_msg(pos)
data.put_data(tmp)
var id = data.get_uint32()
assert(id == 2)
var bitstreamfield = BitStreamField.new()
bitstreamfield.put_id(id)
bitstreamfield.put_msgin(data)
index = bitstreamqueue.put_bitstreamfield(bitstreamfield)
assert(index == 0)
assert(bitstreamqueue.length() == 1)
res = bitstreamqueue.get_msg(index)
#print(res.show())
assert(res.show() == "0000000000000000000000000000001000000111")
assert(res.get_msgin().show() == "0000000000000000000000000000001000000111")
assert(res.get_id() == 2)
func test_msg_3():
var bitstreamqueue = BitStreamQueue.new()
var index
var res
var tmp = PoolByteArray()
tmp.append(0)
tmp.append(0)
tmp.append(0)
tmp.append(2)
tmp.append(7)
var data = BitStream.new()
assert(bitstreamqueue.length() == 0)
data.put_data(tmp)
var id = data.get_uint32()
assert(id == 2)
var bitstreamfield = BitStreamField.new()
bitstreamfield.put_id(id)
bitstreamfield.put_msgin(data)
index = bitstreamqueue.put_bitstreamfield(bitstreamfield)
assert(index == 0)
assert(bitstreamqueue.length() == 1)
res = bitstreamqueue.get_msg(index)
#print(res.show())
assert(res.get_msgin().show() == "0000000000000000000000000000001000000111")
assert(res.get_id() == 2)
tmp = PoolByteArray()
tmp.append(0)
tmp.append(0)
tmp.append(0)
tmp.append(3)
tmp.append(2)
data = BitStream.new()
assert(bitstreamqueue.length() == 1)
data.put_data(tmp)
id = data.get_uint32()
assert(id == 3)
bitstreamfield = BitStreamField.new()
bitstreamfield.put_id(id)
bitstreamfield.put_msgin(data)
index = bitstreamqueue.put_bitstreamfield(bitstreamfield)
assert(index == 1)
assert(bitstreamqueue.length() == 2)
res = bitstreamqueue.get_msg(index)
#print(res.show())
assert(res.get_msgin().show() == "0000000000000000000000000000001100000010")
assert(res.get_id() == 3)
tmp = PoolByteArray()
tmp.append(0)
tmp.append(0)
tmp.append(0)
tmp.append(1)
tmp.append(2)
data = BitStream.new()
assert(bitstreamqueue.length() == 2)
data.put_data(tmp)
id = data.get_uint32()
assert(id == 1)
bitstreamfield = BitStreamField.new()
bitstreamfield.put_id(id)
bitstreamfield.put_msgin(data)
index = bitstreamqueue.put_bitstreamfield(bitstreamfield)
assert(index == 2)
assert(bitstreamqueue.length() == 3)
res = bitstreamqueue.get_msg(index)
#print(res.show())
assert(res.get_msgin().show() == "0000000000000000000000000000000100000010")
assert(res.get_id() == 1)
assert(bitstreamqueue.length() == 3)
bitstreamqueue.erase_id(1)
assert(bitstreamqueue.length() == 2)
func step(id, data, bitstreamqueue):
var tmp = PoolByteArray()
tmp.append(0)
tmp.append(0)
tmp.append(0)
tmp.append(id)
tmp.append(data)
data = BitStream.new()
data.put_data(tmp)
var lid = data.get_uint32()
assert(lid == id)
var bitstreamfield = BitStreamField.new()
bitstreamfield.put_id(id)
bitstreamfield.put_msgin(data)
return bitstreamqueue.put_bitstreamfield(bitstreamfield)
func test_msg_4():
var bitstreamqueue = BitStreamQueue.new()
var index1
var index2
var index3
var index4
assert(bitstreamqueue.length() == 0)
index1 = step(1,1,bitstreamqueue)
assert(bitstreamqueue.length() == 1)
index2 = step(2,2,bitstreamqueue)
assert(bitstreamqueue.length() == 2)
index3 = step(3,3,bitstreamqueue)
assert(bitstreamqueue.length() == 3)
bitstreamqueue.erase_id(2)
assert(bitstreamqueue.length() == 2)
index4 = step(4,4,bitstreamqueue)
assert(bitstreamqueue.length() == 3)
index3 = step(5,5,bitstreamqueue)
assert(bitstreamqueue.length() == 4)
res = bitstreamqueue.get_received_number(pos)
assert(res == 2)
func test():
@ -81,4 +225,6 @@ func test():
test_init()
test_msg_1()
test_msg_2()
test_msg_3()
test_msg_4()
print("[bitstreamqueue] Start check -> end")

View file

@ -147,7 +147,6 @@ margin_right = 627.0
margin_bottom = 188.0
[node name="checkboxs_box" type="VBoxContainer" parent="h_box_container/v_box_container/margin_container/login_box/h_box_container"]
editor/display_folded = true
margin_right = 228.0
margin_bottom = 40.0

View file

@ -336,6 +336,14 @@ void BitStream::put_data(PoolByteArray value)
this->_pos = value.size() * 8;
}
void BitStream::put_bitstream(Ref<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 value;

View file

@ -65,6 +65,8 @@ public:
PoolByteArray get_data();
void put_data(PoolByteArray value);
void put_bitstream(Ref<BitStream> value);
uint32_t get_serial(uint32_t nbits);
bool get_bool();
int8_t get_sint8();

View file

@ -23,130 +23,116 @@
#include "bitstreamqueue.h"
#include "core/os/os.h"
void BitStreamField::_bind_methods()
{
ClassDB::bind_method(D_METHOD("get_id"), &BitStreamField::get_id);
ClassDB::bind_method(D_METHOD("get_msgin"), &BitStreamField::get_msgin);
ClassDB::bind_method(D_METHOD("put_id", "id"), &BitStreamField::put_id);
ClassDB::bind_method(D_METHOD("put_msgin", "msgin"), &BitStreamField::put_msgin);
}
void BitStreamQueue::_bind_methods()
{
ClassDB::bind_method(D_METHOD("clear"), &BitStreamQueue::clear);
ClassDB::bind_method(D_METHOD("length"), &BitStreamQueue::length);
ClassDB::bind_method(D_METHOD("put_msgbytes", "msgbytes"), &BitStreamQueue::put_msgbytes);
ClassDB::bind_method(D_METHOD("get_msg", "pos"), &BitStreamQueue::get_msg);
ClassDB::bind_method(D_METHOD("get_received_number", "pos"), &BitStreamQueue::get_received_number);
ClassDB::bind_method(D_METHOD("erase", "pos"), &BitStreamQueue::erase);
// ClassDB::bind_method(D_METHOD("put_msgbytes", "msgbytes"), &BitStreamQueue::put_msgbytes);
ClassDB::bind_method(D_METHOD("get_msg", "index"), &BitStreamQueue::get_msg);
ClassDB::bind_method(D_METHOD("get_msg_withid", "id"), &BitStreamQueue::get_msg_withid);
ClassDB::bind_method(D_METHOD("put_bitstreamfield", "data"), &BitStreamQueue::put_bitstreamfield);
ClassDB::bind_method(D_METHOD("erase_index", "index"), &BitStreamQueue::erase_index);
ClassDB::bind_method(D_METHOD("erase_id", "id"), &BitStreamQueue::erase_id);
ClassDB::bind_method(D_METHOD("get_index", "id"), &BitStreamQueue::get_index);
ClassDB::bind_method(D_METHOD("is_index", "id"), &BitStreamQueue::is_index);
}
BitStreamQueue::BitStreamQueue()
{
OS::get_singleton()->print("[%s:%d] new BitStreamQueue\n", __FILE__, __LINE__);
for(int i = 0 ; i < SIZE_QUEUE_MESSAGE ; ++i )
this->_msgin[i].instance();
//this->_msgin.resize(SIZE_QUEUE_MESSAGE);
this->clear();
}
BitStreamQueue::~BitStreamQueue()
{
OS::get_singleton()->print("[%s:%d] delete BitStreamQueue\n", __FILE__, __LINE__);
this->clear();
//for(int i = 0 ; i < SIZE_QUEUE_MESSAGE ; ++i ) this->_msgin[i].unref();
for(int i = 0 ; i < SIZE_QUEUE_MESSAGE ; ++i )
{
//OS::get_singleton()->print("[%s:%d] delete BitStreamQueue %d\n", __FILE__, __LINE__, i);
this->_msgin[i].unref();
if (this->_msgin[i] != nullptr)
{
OS::get_singleton()->print("[%s:%d] delete BitStreamQueue %d : KO\n", __FILE__, __LINE__, i);
//memdelete(this->_msgin[i]);
//this->_msgin[i] = nullptr;
}
else
{
OS::get_singleton()->print("[%s:%d] delete BitStreamQueue %d : ok\n", __FILE__, __LINE__, i);
}
}
}
void BitStreamQueue::clear()
{
for(int i = 0 ; i < SIZE_QUEUE_MESSAGE ; ++i )
{
this->_received_number[i] = 0;
//this->_msgin[i].nref();
this->_msgin[i]->clear();
}
this->_size = 0;
this->_msg.clear();
}
int BitStreamQueue::length()
{
return this->_size;
return this->_msg.size();
}
int BitStreamQueue::put_msgbytes(PoolByteArray msgbytes)
int BitStreamQueue::get_index(uint32_t id)
{
int i = 0;
int ii ;
while((i < SIZE_QUEUE_MESSAGE)&&(this->_msgin[i]->size_data() != 0))
++i;
if(i >= SIZE_QUEUE_MESSAGE) // Out of memory
for (int i = 0; i < this->_msg.size(); i++)
{
ERR_PRINTS("Network queue is full (" + itos(i) + " / " + itos(SIZE_QUEUE_MESSAGE) + ")");
throw "Out of memory";
}
this->_msgin[i]->put_data(msgbytes);
uint32_t current_received_number = this->_msgin[i]->get_uint32();
this->_received_number[i] = current_received_number;
if (this->_msg[i]->get_id() == id)
{
return i;
};
};
return -1;
}
// Check we don't have other message with same _received_number (also remove it)
ii = i + 1;
while(ii < SIZE_QUEUE_MESSAGE)
bool BitStreamQueue::is_index(uint32_t id)
{
for (int i = 0; i < this->_msg.size(); i++)
{
if ( this->_received_number[ii] == current_received_number)
this->erase(ii);
++ii;
if (this->_msg[i]->get_id() == id)
{
return true;
};
};
return false;
}
int BitStreamQueue::put_bitstreamfield(Ref<BitStreamField> data)
{
int i = this->get_index(data->get_id());
if (i == -1)
{
this->_msg.push_back(data);
i = this->get_index(data->get_id());
}
this->_size ++;
return i;
}
Ref<BitStream> BitStreamQueue::get_msg(int pos)
Ref<BitStreamField> BitStreamQueue::get_msg_withid(uint32_t id)
{
//Ref<BitStream> ret;
if ( pos >= SIZE_QUEUE_MESSAGE )
for (int i = 0; i < this->_msg.size(); i++)
{
ERR_PRINT("Try to get data out of memory");
throw "Out of memory";
}
//ret.instance();
//*ret = &(this->_msgin[pos]);
//return ret;
//return Ref<BitStream>(this->_msgin[pos]);
//return & (this->_msgin[pos]);
return this->_msgin[pos];
if (this->_msg[i]->get_id() == id)
{
return this->_msg[i];
};
};
return NULL;
}
uint32_t BitStreamQueue::get_received_number(int pos)
Ref<BitStreamField> BitStreamQueue::get_msg(int index)
{
if ( pos >= SIZE_QUEUE_MESSAGE )
{
ERR_PRINT("Try to get data out of memory");
throw "Out of memory";
}
return this->_received_number[pos];
ERR_FAIL_INDEX_V(index, this->_msg.size(), NULL);
return this->_msg[index];
}
void BitStreamQueue::erase(int pos)
void BitStreamQueue::erase_index(int index)
{
if ( pos >= SIZE_QUEUE_MESSAGE )
{
ERR_PRINT("Try to erase data out of memory");
return;
}
this->_received_number[pos] = 0;
this->_msgin[pos]->clear();
this->_size -- ;
ERR_FAIL_INDEX(index, this->_msg.size());
this->_msg.remove(index);
}
void BitStreamQueue::erase_id(uint32_t id)
{
for (int i = 0; i < this->_msg.size(); i++)
{
if (this->_msg[i]->get_id() == id) {
this->_msg.remove(i);
return;
};
};
}

View file

@ -26,25 +26,41 @@
#include "core/reference.h"
#include "modules/bitstream/bitstream.h"
class BitStreamQueue : public Reference {
class BitStreamField : public Reference
{
GDCLASS(BitStreamField, Reference)
protected:
static void _bind_methods();
private:
uint32_t _id;
Ref<BitStream> _msgin;
public:
uint32_t get_id() const { return this->_id; }
Ref<BitStream> get_msgin() { return this->_msgin; }
void put_id(uint32_t id) { this->_id = id; }
void put_msgin(const Ref<BitStream> & msgin) { this->_msgin = msgin; }
};
class BitStreamQueue : public Reference
{
GDCLASS(BitStreamQueue, Reference)
protected:
static void _bind_methods();
private:
int _size;
uint32_t _received_number[SIZE_QUEUE_MESSAGE];
Ref<BitStream> _msgin[SIZE_QUEUE_MESSAGE];
//Vector<BitStream> _msgin;
Vector<Ref<BitStreamField> > _msg;
public:
BitStreamQueue();
~BitStreamQueue();
void clear();
int length();
int put_msgbytes(PoolByteArray msgbytes);
Ref<BitStream> get_msg(int pos);
uint32_t get_received_number(int pos);
void erase(int pos);
bool is_index(uint32_t id);
int get_index(uint32_t id);
int put_bitstreamfield(Ref<BitStreamField> data);
Ref<BitStreamField> get_msg(int index);
Ref<BitStreamField> get_msg_withid(uint32_t id);
void erase_index(int index);
void erase_id(uint32_t id);
};
#endif // BIT_STREAM_QUEUE_H

View file

@ -8,7 +8,7 @@ def configure(env):
def get_doc_classes():
return [
"BitStreamQueue",
"BitStreamQueue", "BitStreamField"
]
def get_doc_path():

View file

@ -6,6 +6,7 @@
#include "bitstreamqueue.h"
void register_bitstreamqueue_types() {
ClassDB::register_class<BitStreamField>();
ClassDB::register_class<BitStreamQueue>();
}

View file

@ -0,0 +1,40 @@
/*
Check Memory
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 "check_memory.h"
#include "core/os/os.h"
uint64_t memstaticold = 0;
uint64_t memdynamicold = 0;
uint64_t mempeakold = 0;
void show_memory_usage()
{
uint64_t memstatic = OS::get_singleton()->get_static_memory_usage();
uint64_t memdynamic = OS::get_singleton()->get_dynamic_memory_usage();
uint64_t mempeak = OS::get_singleton()->get_static_memory_peak_usage();
OS::get_singleton()->print("[%s:%d] Usage Memory - Current [Static:%ld, Dynamic:%ld, Peak:%ld] Delta [Static:%ld, Dynamic:%ld, Peak:%ld]\n",
__FILE__, __LINE__,
memstatic, memdynamic, mempeak,
memstatic - memstaticold, memdynamic - memdynamicold, mempeak - mempeakold);
memstaticold = memstatic;
memdynamicold = memdynamic;
mempeakold = mempeak;
}

View file

@ -0,0 +1,32 @@
/*
Check Memory
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 MEMORY_CHECK_H
#define MEMORY_CHECK_H
void show_memory_usage();
#ifdef ENABLE_CHECK_MEMORY_USAGE
#define SHOW_USAGE_MEMORY show_memory_usage();
#else
#define SHOW_USAGE_MEMORY
#endif
#endif

View file

@ -0,0 +1,19 @@
/*
Library to manage message received from server
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/>.
*/

View file

@ -0,0 +1,46 @@
/*
Header MessageQueue
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 MESSAGEQUEUE_H
#define MESSAGEQUEUE_H
/*
class Message
{
public:
virtual void send_message(PoolByteArray & msgbytes);
};
class MessageDirect : public Message
{
public:
void send_message(uint32_t msgid, PoolByteArray & msgbytes);
};
// Class store message and execute if is correct ID
class MessageQueue : public Message
{
BitStreamQueue queue;
public:
void send_message(uint32_t msgid, PoolByteArray & msgbytes);
};
*/
#endif // MESSAGEQUEUE_H

View file

@ -27,12 +27,10 @@ void NetworkConnection::_bind_methods()
ClassDB::bind_method(D_METHOD("define_server", "host", "port"), &NetworkConnection::define_server);
ClassDB::bind_method(D_METHOD("define_user", "user_addr", "user_key", "user_id"), &NetworkConnection::define_user);
ClassDB::bind_method(D_METHOD("define_lang", "lang"), &NetworkConnection::define_lang);
ClassDB::bind_method(D_METHOD("send_system_login"), &NetworkConnection::send_system_login);
ClassDB::bind_method(D_METHOD("send_system_disconnect"), &NetworkConnection::send_system_disconnect);
ClassDB::bind_method(D_METHOD("send_system_quit"), &NetworkConnection::send_system_quit);
ClassDB::bind_method(D_METHOD("disconnect_server"), &NetworkConnection::disconnect_server);
ClassDB::bind_method(D_METHOD("process", "delta"), &NetworkConnection::process);
ClassDB::bind_method(D_METHOD("get_state"), &NetworkConnection::get_state);
ClassDB::bind_method(D_METHOD("connect_to_server"), &NetworkConnection::connect_to_server);
ClassDB::bind_method(D_METHOD("terminate_network_connection"), &NetworkConnection::terminate_network_connection);
//ClassDB::bind_method(D_METHOD("get_master_message_description_node"), &NetworkConnection::get_master_message_description_node);
}
@ -70,21 +68,11 @@ void NetworkConnection::define_lang(String lang)
NetworkConnectionCore::get_singleton()->define_lang(lang);
}
void NetworkConnection::send_system_login()
void NetworkConnection::connect_to_server()
{
NetworkConnectionCore::get_singleton()->send_system_login();
NetworkConnectionCore::get_singleton()->connect_to_server();
}
void NetworkConnection::send_system_disconnect()
{
NetworkConnectionCore::get_singleton()->send_system_disconnect();
}
void NetworkConnection::send_system_quit()
{
NetworkConnectionCore::get_singleton()->send_system_quit();
}
void NetworkConnection::disconnect_server()
{
NetworkConnectionCore::get_singleton()->disconnect_server();

View file

@ -40,9 +40,7 @@ public:
void define_server(String host, int64_t port);
void define_user(String user_addr, String user_key, String user_id);
void define_lang(String lang);
void send_system_login();
void send_system_disconnect();
void send_system_quit();
void connect_to_server();
void disconnect_server();
void process(int delta);
int get_state();

View file

@ -18,6 +18,9 @@
*/
#define ENABLE_CHECK_MEMORY_USAGE
#include "check_memory.h"
#include "network_connection_core.h"
NetworkConnectionCore *NetworkConnectionCore::singleton = nullptr;
@ -38,10 +41,9 @@ void NetworkConnectionCore::cleanup()
OS::get_singleton()->print("NetworkConnectionCore::cleanup\n");
}
NetworkConnectionCore::NetworkConnectionCore()
NetworkConnectionCore::NetworkConnectionCore() : _state_not_initialized(this), _state_login(this), _state_synchronize(this), _state_connected(this), _state_quit(this)
{
//this->_socketUDP = nullptr;
this->_state = STATE::NotInitialised;
this->_state_connexion = & this->_state_not_initialized;
}
NetworkConnectionCore::~NetworkConnectionCore()
@ -59,12 +61,15 @@ NetworkConnectionCore::~NetworkConnectionCore()
}
NetworkConnectionCore::singleton = nullptr;
this->_state = STATE::NotInitialised;
this->_state_connexion = & this->_state_not_initialized;
//this->_state = STATE::NotInitialised;
}
int NetworkConnectionCore::get_state()
{
return this->_state;
return this->_state_connexion->get_state();
}
void NetworkConnectionCore::autodefine_socket_udp()
@ -81,10 +86,23 @@ void NetworkConnectionCore::autodefine_socket_udp()
}
}
void NetworkConnectionCore::open_network()
{
this->autodefine_socket_udp();
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);
}
void NetworkConnectionCore::close_network()
{
this->_socketUDP->close();
this->_socketUDP.unref();
}
void NetworkConnectionCore::define_checksum_msg_xml(Array & checksum_msg_xml)
{
this->_network_data.define_checksum_msg_xml(checksum_msg_xml);
//DEBUG_PRINT("Received msg.xml checksum");
this->_checksum_msg_xml = checksum_msg_xml;
//this->_checksum_msg_xml = checksum_msg_xml;
//DEBUG_PRINT("Received msg.xml checksum " + itos(checksum_msg_xml.size()));
//DEBUG_PRINT("Received msg.xml checksum " + itos(this->_checksum_msg_xml.size()));
}
@ -97,77 +115,22 @@ void NetworkConnectionCore::define_server(String host, int64_t port)
void NetworkConnectionCore::define_user(String user_addr, String user_key, String user_id)
{
this->_user_addr = user_addr;
this->_user_key = user_key;
this->_user_id = user_id;
this->_network_data.define_user(user_addr, user_key, user_id);
}
void NetworkConnectionCore::define_lang(String lang)
{
this->_lang = lang;
this->_network_data.define_lang(lang);
}
void NetworkConnectionCore::initialize()
{
// Initialize counter
this->_current_received_number = 0;
this->_last_received_number = 0;
this->_quit_id = 0;
this->_long_ack_bit_field.resize(NUM_BITS_IN_LONG_ACK);
this->_latest_probes.clear();
this->_ack_bit_mask = 0;
this->_last_ack_bit = 0;
this->_last_ack_in_long_ack = 0;
this->_current_server_tick = 0;
this->_current_client_tick = 0;
this->_ms_per_tick = 100;
this->_current_client_time = 0;
this->_network_data.initialize();
}
/*
* Login
*/
void NetworkConnectionCore::send_system_login()
void NetworkConnectionCore::connect_to_server()
{
// Configure socket UDP
this->autodefine_socket_udp();
if ( this->_state != STATE::NotInitialised )
{
// DEBUG_PRINT("Close old network socket");
this->_socketUDP->close();
}
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);
// Open connection and send ID
BitStream msgout;
msgout.put_uint32(_current_received_number);
msgout.put_bool(true);
msgout.put_uint8(CLFECOMMON::SYSTEM_LOGIN_CODE);
msgout.put_string_hexa32(this->_user_addr);
msgout.put_string_hexa32(this->_user_key);
msgout.put_string_hexa32(this->_user_id);
msgout.put_string(this->_lang);
Error ret;
ret = this->_socketUDP->put_packet_buffer(msgout.get_data()); // , msgout.get_data().size()
if ( ret != Error::OK)
{
this->_socketUDP->close();
switch(ret)
{
case Error::ERR_CANT_CONNECT:
ERR_PRINT("network connexion - Can't connect");
default:
ERR_PRINT("network connexion - Unknown error");
}
return;
}
OS::get_singleton()->print("Connected to khganat\n");
this->_state = STATE::Login;
// Initialize counter
this->initialize();
this->_state_connexion->connect_to_server();
}
/*
@ -176,6 +139,8 @@ void NetworkConnectionCore::send_system_login()
void NetworkConnectionCore::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;
@ -190,7 +155,8 @@ void NetworkConnectionCore::send_system_quit()
{
ERR_PRINT("Error to send disconnect");
}
this->_state = STATE::Quit;
//this->_state = STATE::Quit;
*/
}
/*
@ -199,6 +165,8 @@ void NetworkConnectionCore::send_system_quit()
void NetworkConnectionCore::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__);
@ -213,6 +181,7 @@ void NetworkConnectionCore::send_system_disconnect()
}
this->_socketUDP->close();
this->_state = STATE::Disconnect;
*/
}
/*
@ -221,17 +190,18 @@ void NetworkConnectionCore::send_system_disconnect()
void NetworkConnectionCore::disconnect_server()
{
if (this->_state != STATE::Connected && this->_state != STATE::ForceSynchronize)
return;
// if (this->_state != STATE::Connected && this->_state != STATE::ForceSynchronize) return;
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__);
@ -257,9 +227,11 @@ void NetworkConnectionCore::send_system_ack_sync()
msgout.unref();
this->_state = STATE::Connected;
}
*/
void NetworkConnectionCore::receive_system_sync(Ref<BitStream> msgin)
{
/*
int i;
bool valide = true;
@ -301,6 +273,7 @@ void NetworkConnectionCore::receive_system_sync(Ref<BitStream> msgin)
}
else
ERR_PRINTS("MSG.XML is wrong");
*/
}
/*
@ -309,12 +282,15 @@ void NetworkConnectionCore::receive_system_sync(Ref<BitStream> msgin)
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)
@ -347,9 +323,10 @@ void NetworkConnectionCore::send_system_ack_probe()
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->_queue.clear();
this->_state = STATE::Connected;
}
*/
}
/*
@ -358,6 +335,7 @@ void NetworkConnectionCore::send_system_ack_probe()
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();
@ -387,6 +365,7 @@ void NetworkConnectionCore::wait_resynchronize(uint32_t current_received_number,
}
}
this->_last_received_number = current_received_number;
*/
}
/*
@ -395,6 +374,7 @@ void NetworkConnectionCore::wait_resynchronize(uint32_t current_received_number,
void NetworkConnectionCore::decode_system_message(Ref<BitStream> msgin)
{
/*
int message = msgin->get_uint8();
switch (message)
{
@ -419,6 +399,7 @@ void NetworkConnectionCore::decode_system_message(Ref<BitStream> msgin)
ERR_PRINTS("Received unknown message [" + itos(message) + "]");
break;
}
*/
}
void NetworkConnectionCore::decode_normal_message(Ref<BitStream> msgin)
@ -432,6 +413,7 @@ void NetworkConnectionCore::decode_normal_message(Ref<BitStream> msgin)
void NetworkConnectionCore::analyze_message_received(uint32_t current_received_number, Ref<BitStream> msgin)
{
/*
bool system_mode;
bool ackBool = false;
int ackBit = 0;
@ -501,66 +483,109 @@ void NetworkConnectionCore::analyze_message_received(uint32_t current_received_n
this->decode_system_message(msgin);
else
this->decode_normal_message(msgin);
*/
}
void NetworkConnectionCore::store_message_received(PoolByteArray & msgbytes)
void NetworkConnectionCore::store_message_received(PoolByteArray msgbytes)
{
int pos = this->queue.put_msgbytes(msgbytes);
/*
Ref<BitStream> msgin;
msgin.instance();
msgin->put_data(msgbytes);
uint32_t current_received_number = msgin->get_uint32();
Ref<BitStream> msgin = this->queue.get_msg(pos);
uint32_t current_received_number = this->queue.get_received_number(pos);
//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);
// 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(pos);
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(pos);
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)
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)
{
if (this->_state == STATE::Disconnect || this->_state == STATE::NotInitialised)
// this->_state_connexion->process(delta);
if ( this->_socketUDP.is_null() )
return;
OS::get_singleton()->print( "[%s:%d] Process - delta : %d\n", __FILE__, __LINE__, delta);
//OS::get_singleton()->print("[%s:%d] process ...\n", __FILE__, __LINE__);
// if (this->_state == STATE::Disconnect || this->_state == STATE::NotInitialised) return;
//OS::get_singleton()->print( "[%s:%d] Process - delta : %d\n", __FILE__, __LINE__, delta);
for(int i = 0; (this->_socketUDP->get_available_packet_count() > 0) && (i < MAX_LOOP_READ_BY_STEP) ; ++i)
{
PoolByteArray msgbytes ;
this->_socketUDP->get_packet_buffer(msgbytes);
OS::get_singleton()->print("[%s:%d] Size msg received: %d\n", __FILE__, __LINE__, msgbytes.size());
store_message_received(msgbytes);
OS::get_singleton()->print("[%s:%d] Size msg received: %d (i:%d, state:%d, size queue:%d)\n", __FILE__, __LINE__, msgbytes.size(), i, this->get_state(), this->_queue.length());
SHOW_USAGE_MEMORY
// store_message_received(msgbytes);
Ref<BitStream> msgin;
msgin.instance();
msgin->put_data(msgbytes);
uint32_t current_received_number = msgin->get_uint32();
Ref<BitStreamField> msg;
msg.instance();
msg->put_id(current_received_number);
msg->put_msgin(msgin);
int index = this->_queue.put_bitstreamfield(msg);
msgin.unref();
msg.unref();
this->_state_connexion->receive_message(index);
}
send_message();
this->_state_connexion->send_message();
//OS::get_singleton()->print("[%s:%d] --------------------------------\n", __FILE__, __LINE__);
}
bool NetworkConnectionCore::is_active()

View file

@ -25,37 +25,10 @@
#include "core/io/packet_peer_udp.h"
#include "modules/bitset/bitset.h"
#include "modules/bitstreamqueue/bitstreamqueue.h"
#include "state_connexion.h"
#include "network_data.h"
#define MAX_LOOP_READ_BY_STEP 10
#define NUM_BITS_IN_LONG_ACK 512
enum STATE {
NotInitialised = 0,
//NotConnected = 1, // When received a cookie - not used here
//Authenticate = 2,
Login = 3,
Synchronize = 4,
Connected = 5, // State when we are connecte
//Probe = 6,
//Stalled = 7,
Disconnect = 8,
Quit = 9,
ForceSynchronize = 10
};
enum CLFECOMMON {
SYSTEM_LOGIN_CODE = 0,
SYSTEM_SYNC_CODE = 1,
SYSTEM_ACK_SYNC_CODE = 2,
SYSTEM_PROBE_CODE = 3,
SYSTEM_ACK_PROBE_CODE = 4,
SYSTEM_DISCONNECTION_CODE = 5,
SYSTEM_STALLED_CODE = 6,
SYSTEM_SERVER_DOWN_CODE = 7,
SYSTEM_QUIT_CODE = 8,
SYSTEM_ACK_QUIT_CODE = 9,
NUMBITSINLONGACK = 512
};
#define LCT 100
@ -63,35 +36,34 @@ class NetworkConnectionCore : public Reference {
GDCLASS(NetworkConnectionCore, Reference)
private:
static NetworkConnectionCore *singleton;
friend class StateConnectionBase;
friend class StateConnectionNotInitialized;
friend class StateConnectionLogin;
friend class StateConnectionSynchronize;
friend class StateConnectionConnected;
friend class StateConnectionQuit;
STATE _state;
uint32_t _ack_bit_mask;
uint32_t _current_server_tick;
uint32_t _current_client_tick;
uint32_t _synchronize;
uint32_t _current_received_number;
uint32_t _last_received_number;
uint32_t _ms_per_tick;
uint32_t _current_client_time;
uint32_t _update_time;
int32_t _quit_id;
int32_t _last_ack_bit;
uint32_t _last_ack_in_long_ack;
int32_t _latest_sync;
protected:
int64_t _port;
String _host;
String _lang;
String _user_addr;
String _user_key;
String _user_id;
Ref<PacketPeerUDP> _socketUDP;
BitSet _long_ack_bit_field;
Array _latest_probes;
Array _checksum_msg_xml;
BitStreamQueue queue;
BitStreamQueue _queue;
StateConnectionNotInitialized _state_not_initialized;
StateConnectionLogin _state_login;
StateConnectionSynchronize _state_synchronize;
StateConnectionConnected _state_connected;
StateConnectionQuit _state_quit;
StateConnectionBase * _state_connexion;
NetworkData _network_data;
//MessageDescriptionNode _message_description_node;
void open_network();
void close_network();
public:
static NetworkConnectionCore * get_singleton();
@ -110,8 +82,8 @@ public:
void define_lang(String lang);
void initialize();
void connect_to_server();
void send_system_login();
void send_system_disconnect();
void send_system_quit();
void disconnect_server();
@ -126,7 +98,7 @@ public:
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 store_message_received(PoolByteArray msgbytes);
void send_message();
void process(int delta);
bool connected();
@ -135,5 +107,4 @@ public:
//MessageDescriptionNode & get_master_message_description_node();
};
#endif

View file

@ -0,0 +1,70 @@
/*
Library NetworkData
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 "network_data.h"
NetworkData::NetworkData()
{
this->initialize();
}
NetworkData::~NetworkData()
{
}
void NetworkData::initialize()
{
// Initialize counter
this->_current_received_number = 0;
this->_last_received_number = 0;
this->_quit_id = 0;
this->_long_ack_bit_field.resize(NUM_BITS_IN_LONG_ACK);
this->_latest_probes.clear();
this->_ack_bit_mask = 0;
this->_last_ack_bit = 0;
this->_last_ack_in_long_ack = 0;
this->_current_server_tick = 0;
this->_current_client_tick = 0;
this->_ms_per_tick = 100;
this->_current_client_time = 0;
this->_server_sync = 0;
this->_client_sync = 0;
}
void NetworkData::define_lang(String lang)
{
this->_lang = lang;
}
void NetworkData::define_user(String user_addr, String user_key, String user_id)
{
this->_user_addr = user_addr;
this->_user_key = user_key;
this->_user_id = user_id;
}
void NetworkData::define_checksum_msg_xml(Array & checksum_msg_xml)
{
//DEBUG_PRINT("Received msg.xml checksum");
this->_checksum_msg_xml = checksum_msg_xml;
//DEBUG_PRINT("Received msg.xml checksum " + itos(checksum_msg_xml.size()));
//DEBUG_PRINT("Received msg.xml checksum " + itos(this->_checksum_msg_xml.size()));
}

View file

@ -0,0 +1,74 @@
/*
Header NetworkData
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 NETWORK_DATA_H
#define NETWORK_DATA_H
// #include "core/reference.h"
// #include "core/io/packet_peer_udp.h"
#include "modules/bitset/bitset.h"
#include "core/ustring.h"
#define MAX_LOOP_READ_BY_STEP 10
#define NUM_BITS_IN_LONG_ACK 512
class NetworkData
{
public:
uint32_t _ack_bit_mask;
uint32_t _current_server_tick;
uint32_t _current_client_tick;
uint32_t _synchronize;
uint32_t _current_received_number;
uint32_t _last_received_number;
uint32_t _ms_per_tick;
uint32_t _current_client_time;
uint32_t _update_time;
int32_t _quit_id;
int32_t _last_ack_bit;
uint32_t _last_ack_in_long_ack;
int32_t _client_sync;
int32_t _server_sync;
String _lang;
String _user_addr;
String _user_key;
String _user_id;
BitSet _long_ack_bit_field;
Array _latest_probes;
Array _checksum_msg_xml;
NetworkData();
~NetworkData();
void initialize();
void define_lang(String lang);
void define_user(String user_addr, String user_key, String user_id);
void define_checksum_msg_xml(Array & checksum_msg_xml);
};
#endif

View file

@ -0,0 +1,417 @@
/*
Library to manage state connexion
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 "check_memory.h"
#include "state_connexion.h"
#include "network_connection_core.h"
/*
* StateConnectionBase
*/
StateConnectionBase::StateConnectionBase(NetworkConnectionCore * network)
{
this->_network = network;
this->_data = & (network->_network_data);
}
/*
* StateConnectionNotInitialized
*/
void StateConnectionNotInitialized::connect_to_server()
{
this->_network->_queue.clear();
this->_network->open_network();
this->_network->_state_connexion = & this->_network->_state_login;
OS::get_singleton()->print("[%s:%d] connect_to_server\n", __FILE__, __LINE__);
}
/*
* StateConnectionLogin
*/
void StateConnectionLogin::send_system_quit()
{
OS::get_singleton()->print("[%s:%d] send quit to server\n", __FILE__, __LINE__);
BitStream msgout;
msgout.put_uint32(this->_data->_current_received_number);
msgout.put_bool(true);
msgout.put_uint8(CLFECOMMON::SYSTEM_QUIT_CODE);
msgout.put_sint32(this->_data->_quit_id);
if ( this->_network->_socketUDP->put_packet_buffer(msgout.get_data()) != Error::OK )
{
ERR_PRINT("Error to send disconnect");
}
this->_network->_state_connexion = & this->_network->_state_quit;
}
void StateConnectionLogin::send_message()
{
BitStream msgout;
msgout.put_uint32(this->_data->_current_received_number);
msgout.put_bool(true);
msgout.put_uint8(CLFECOMMON::SYSTEM_LOGIN_CODE);
msgout.put_string_hexa32(this->_data->_user_addr);
msgout.put_string_hexa32(this->_data->_user_key);
msgout.put_string_hexa32(this->_data->_user_id);
msgout.put_string(this->_data->_lang);
Error ret;
ret = this->_network->_socketUDP->put_packet_buffer(msgout.get_data()); // , msgout.get_data().size()
if ( ret != Error::OK)
{
this->_network->close_network();
switch(ret)
{
case Error::ERR_CANT_CONNECT:
ERR_PRINT("network connexion - Can't connect");
default:
ERR_PRINT("network connexion - Unknown error");
}
return;
}
OS::get_singleton()->print("[%s:%d] Connected to khganat\n", __FILE__, __LINE__);
this->_network->_state_connexion = & this->_network->_state_synchronize;
}
/*
* StateConnectionSynchronize
*/
void StateConnectionSynchronize::send_system_quit()
{
OS::get_singleton()->print("[%s:%d] send quit to server\n", __FILE__, __LINE__);
BitStream msgout;
msgout.put_uint32(this->_data->_current_received_number);
msgout.put_bool(true);
msgout.put_uint8(CLFECOMMON::SYSTEM_QUIT_CODE);
msgout.put_sint32(this->_data->_quit_id);
if ( this->_network->_socketUDP->put_packet_buffer(msgout.get_data()) != Error::OK )
{
ERR_PRINT("Error to send quit");
}
this->_network->_state_connexion = & this->_network->_state_quit;
}
void StateConnectionSynchronize::send_system_ack_sync()
{
OS::get_singleton()->print("[%s:%d] send system ACK Sync to server\n", __FILE__, __LINE__);
Ref<BitStream> msgout;
msgout.instance();
msgout->put_uint32(this->_data->_current_received_number);
msgout->put_bool(true);
msgout->put_uint8(CLFECOMMON::SYSTEM_ACK_SYNC_CODE);
msgout->put_sint32(this->_data->_last_received_number);
msgout->put_sint32(this->_data->_last_ack_in_long_ack);
this->_data->_long_ack_bit_field.write_serial(msgout);
msgout->put_sint32(this->_data->_server_sync);
if (this->_network->_socketUDP->put_packet_buffer(msgout->get_data()) != Error::OK)
{
ERR_PRINT("Error to send ack sync");
return;
}
msgout.unref();
this->_data->_client_sync = this->_data->_server_sync;
this->_network->_state_connexion = & this->_network->_state_connected;
}
void StateConnectionSynchronize::receive_system_sync(Ref<BitStream> msgin)
{
bool valide = true;
int i;
OS::get_singleton()->print("[%s:%d] SYSTEM_SYNC_CODE\n", __FILE__, __LINE__);
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->_data->_checksum_msg_xml.size() )
{
valide = false;
ERR_PRINTS("MSG XML is incorrect (server:" + itos(msg_xml.size()) +", client:" + itos(this->_data->_checksum_msg_xml.size()) + ")");
}
else
{
for(i=0; i<msg_xml.size(); ++i)
{
if ( (int) msg_xml[i] != (int) this->_data->_checksum_msg_xml[i] )
{
valide = false;
ERR_PRINTS("MSG XML is incorrect (pos:" + itos(i) +")");
}
}
}
if ( valide == true )
{
OS::get_singleton()->print("[%s:%d] MSG XML is correct\n", __FILE__, __LINE__);
this->_data->_server_sync = latestsync;
this->_data->_synchronize = synchronize;
this->_data->_current_server_tick = this->_data->_synchronize + this->_data->_current_received_number + 2;
this->_data->_current_client_tick = this->_data->_current_server_tick + (LCT + this->_data->_ms_per_tick) / this->_data->_ms_per_tick;
this->_data->_current_client_time = this->_data->_update_time - (LCT + this->_data->_ms_per_tick);
//this->_state = STATE::Synchronize;
}
else
ERR_PRINTS("MSG.XML is wrong");
}
void StateConnectionSynchronize::receive_message(int index)
{
bool system_mode;
OS::get_singleton()->print("[%s:%d] receive_message ...\n", __FILE__, __LINE__);
//this->_data->_current_received_number = current_received_number;
Ref<BitStreamField> field = this->_network->_queue.get_msg(index);
uint32_t current_received_number = field->get_id();
Ref<BitStream> msgin = field->get_msgin();
this->_data->_current_received_number = current_received_number;
//Ref<BitStreamField> msgin = this->_network->_queue.get_msg(index)->get_msgin();
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("[%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:
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:
OS::get_singleton()->print("[%s:%d] SYSTEM_PROBE_CODE\n", __FILE__, __LINE__);
break;
default:
ERR_PRINTS("Received unknown message [" + itos(message) + "]");
break;
}
}
// this->_last_received_number = current_received_number;
this->_network->_queue.erase_index(index);
}
void StateConnectionSynchronize::send_message()
{
//OS::get_singleton()->print("[%s:%d] send_system %d / %d \n", __FILE__, __LINE__, this->_data->_server_sync, this->_data->_client_sync);
if ( this->_data->_server_sync != this->_data->_client_sync )
this->send_system_ack_sync();
}
/*
* StateConnectionConnected
*/
void StateConnectionConnected::send_system_quit()
{
OS::get_singleton()->print("[%s:%d] send quit to server\n", __FILE__, __LINE__);
BitStream msgout;
msgout.put_uint32(this->_data->_current_received_number);
msgout.put_bool(true);
msgout.put_uint8(CLFECOMMON::SYSTEM_QUIT_CODE);
msgout.put_sint32(this->_data->_quit_id);
if ( this->_network->_socketUDP->put_packet_buffer(msgout.get_data()) != Error::OK )
{
ERR_PRINT("Error to send disconnect");
}
this->_network->_state_connexion = & this->_network->_state_quit;
}
void StateConnectionConnected::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->_data->_current_received_number);
msgout.put_bool(true);
msgout.put_uint8(CLFECOMMON::SYSTEM_DISCONNECTION_CODE);
if ( this->_network->_socketUDP->put_packet_buffer(msgout.get_data()) != Error::OK )
{
ERR_PRINT("Error to send disconnect");
}
this->_network->_socketUDP->close();
// this->_state = STATE::Disconnect;
this->_network->_state_connexion = & this->_network->_state_not_initialized;
}
void StateConnectionConnected::send_system_ack_sync()
{
OS::get_singleton()->print("[%s:%d] send system ACK Sync to server\n", __FILE__, __LINE__);
Ref<BitStream> msgout;
msgout.instance();
msgout->put_uint32(this->_data->_current_received_number);
msgout->put_bool(true);
msgout->put_uint8(CLFECOMMON::SYSTEM_ACK_SYNC_CODE);
msgout->put_sint32(this->_data->_last_received_number);
msgout->put_sint32(this->_data->_last_ack_in_long_ack);
this->_data->_long_ack_bit_field.write_serial(msgout);
msgout->put_sint32(this->_data->_server_sync);
if (this->_network->_socketUDP->put_packet_buffer(msgout->get_data()) != Error::OK)
{
ERR_PRINT("Error to send ack sync");
return;
}
msgout.unref();
this->_data->_client_sync = this->_data->_server_sync;
}
void StateConnectionConnected::send_system_ack_probe()
{
// 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 PROBE to server\n", __FILE__, __LINE__);
int max = this->_data->_latest_probes.size() ;
BitStream msgout;
msgout.put_uint32(this->_data->_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->_data->_latest_probes[i];
msgout.put_sint32(data);
}
if (this->_network->_socketUDP->put_packet_buffer(msgout.get_data()) != Error::OK)
{
ERR_PRINT("Error to send disconnect");
return;
}
this->_data->_latest_probes.clear();
}
void StateConnectionConnected::receive_system_sync(Ref<BitStream> msgin)
{
bool valide = true;
int i;
OS::get_singleton()->print("[%s:%d] SYSTEM_SYNC_CODE\n", __FILE__, __LINE__);
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->_data->_checksum_msg_xml.size() )
{
valide = false;
ERR_PRINTS("MSG XML is incorrect (server:" + itos(msg_xml.size()) +", client:" + itos(this->_data->_checksum_msg_xml.size()) + ")");
}
else
{
for(i=0; i<msg_xml.size(); ++i)
{
if ( (int) msg_xml[i] != (int) this->_data->_checksum_msg_xml[i] )
{
valide = false;
ERR_PRINTS("MSG XML is incorrect (pos:" + itos(i) +")");
}
}
}
if ( valide == true )
{
OS::get_singleton()->print("[%s:%d] MSG XML is correct\n", __FILE__, __LINE__);
this->_data->_server_sync = latestsync;
this->_data->_synchronize = synchronize;
this->_data->_current_server_tick = this->_data->_synchronize + this->_data->_current_received_number + 2;
this->_data->_current_client_tick = this->_data->_current_server_tick + (LCT + this->_data->_ms_per_tick) / this->_data->_ms_per_tick;
this->_data->_current_client_time = this->_data->_update_time - (LCT + this->_data->_ms_per_tick);
//this->_state = STATE::Synchronize;
}
else
ERR_PRINTS("MSG.XML is wrong");
}
void StateConnectionConnected::receive_message(int index)
{
// SHOW_USAGE_MEMORY
bool system_mode;
Ref<BitStreamField> field = this->_network->_queue.get_msg(index);
uint32_t current_received_number = field->get_id();
this->_data->_current_received_number = current_received_number;
Ref<BitStream> msgin = field->get_msgin();
system_mode = msgin->get_bool();
if ( system_mode == true )
{
//OS::get_singleton()->print("[%s:%d] system message (%d) [%d]\n", __FILE__, __LINE__, (int)current_received_number, this->_network->_queue.length());
int message = msgin->get_uint8();
switch (message)
{
case CLFECOMMON::SYSTEM_LOGIN_CODE:
OS::get_singleton()->print("[%s:%d] Receive SYSTEM_LOGIN_CODE (%d) [%d]\n", __FILE__, __LINE__, (int)current_received_number, this->_network->_queue.length());
break;
case CLFECOMMON::SYSTEM_SYNC_CODE:
OS::get_singleton()->print("[%s:%d] Receive SYSTEM_SYNC_CODE (%d) [%d]\n", __FILE__, __LINE__, (int)current_received_number, this->_network->_queue.length());
this->receive_system_sync(msgin);
break;
case CLFECOMMON::SYSTEM_STALLED_CODE:
OS::get_singleton()->print("[%s:%d] Receive SYSTEM_STALLED_CODE (%d) [%d]\n", __FILE__, __LINE__, (int)current_received_number, this->_network->_queue.length());
break;
case CLFECOMMON::SYSTEM_SERVER_DOWN_CODE:
OS::get_singleton()->print("[%s:%d] Receive SYSTEM_SERVER_DOWN_CODE (%d) [%d]\n", __FILE__, __LINE__, (int)current_received_number, this->_network->_queue.length());
break;
case CLFECOMMON::SYSTEM_PROBE_CODE:
OS::get_singleton()->print("[%s:%d] Receive SYSTEM_PROBE_CODE (%d) [%d]\n", __FILE__, __LINE__, (int)current_received_number, this->_network->_queue.length());
this->_data->_latest_probes.append(msgin->get_sint32());
break;
default:
OS::get_singleton()->print("[%s:%d] Receive UNKNOWN SYSTEM MESSAGE [id:%d] (%d) [%d]\n", __FILE__, __LINE__, message, (int)current_received_number, this->_network->_queue.length());
//ERR_PRINTS("Received unknown message [" + itos(message) + "]");
break;
}
}
else
{
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);
}
void StateConnectionConnected::send_message()
{
if ( this->_data->_server_sync != this->_data->_client_sync )
this->send_system_ack_sync();
if (this->_data->_latest_probes.size() != 0 )
this->send_system_ack_probe();
}
/*
*
*/

View file

@ -0,0 +1,144 @@
/*
Header NetworkConnectionCore
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 STATE_CONNEXION_H
#define STATE_CONNEXION_H
#include "core/reference.h"
#include "core/io/packet_peer_udp.h"
#include "modules/bitset/bitset.h"
#include "modules/bitstreamqueue/bitstreamqueue.h"
#include "network_data.h"
#define NUM_BITS_IN_LONG_ACK 512
enum STATE {
NotInitialised = 0,
//NotConnected = 1, // When received a cookie - not used here
//Authenticate = 2,
Login = 3,
Synchronize = 4,
Connected = 5, // State when we are connecte
//Probe = 6,
//Stalled = 7,
Disconnect = 8,
Quit = 9,
ForceSynchronize = 10
};
enum CLFECOMMON {
SYSTEM_LOGIN_CODE = 0,
SYSTEM_SYNC_CODE = 1,
SYSTEM_ACK_SYNC_CODE = 2,
SYSTEM_PROBE_CODE = 3,
SYSTEM_ACK_PROBE_CODE = 4,
SYSTEM_DISCONNECTION_CODE = 5,
SYSTEM_STALLED_CODE = 6,
SYSTEM_SERVER_DOWN_CODE = 7,
SYSTEM_QUIT_CODE = 8,
SYSTEM_ACK_QUIT_CODE = 9,
NUMBITSINLONGACK = 512
};
class NetworkConnectionCore;
// Virtual class reference for network state
class StateConnectionBase
{
protected:
NetworkConnectionCore * _network;
NetworkData * _data;
public:
StateConnectionBase(NetworkConnectionCore * network);
~StateConnectionBase() {}
virtual int get_state() {return STATE::NotInitialised;}
virtual void connect_to_server() {}
virtual void send_message() {}
//virtual void send_system_login() {}
virtual void send_system_quit() {}
virtual void send_system_disconnect() {}
// virtual void send_system_ack_sync() {}
virtual void receive_message(int index) {}
virtual void send_system() {}
};
// class define state not initialized
class StateConnectionNotInitialized : public StateConnectionBase
{
public:
StateConnectionNotInitialized(NetworkConnectionCore * network) : StateConnectionBase(network) {}
~StateConnectionNotInitialized() {}
int get_state() {return STATE::NotInitialised;}
void connect_to_server();
};
// class define state login
class StateConnectionLogin : public StateConnectionBase
{
public:
StateConnectionLogin(NetworkConnectionCore * network) : StateConnectionBase(network) {}
~StateConnectionLogin() {}
int get_state() {return STATE::Login;}
void send_system_quit();
void send_message();
};
// class define state synchronize
class StateConnectionSynchronize : public StateConnectionBase
{
public:
StateConnectionSynchronize(NetworkConnectionCore * network) : StateConnectionBase(network) {}
~StateConnectionSynchronize() {}
int get_state() {return STATE::Synchronize;}
void receive_system_sync(Ref<BitStream> msgin);
void send_system_quit();
void send_system_ack_sync();
void receive_message(int index);
void send_message();
};
// class define state connected
class StateConnectionConnected : public StateConnectionBase
{
public:
StateConnectionConnected(NetworkConnectionCore * network) : StateConnectionBase(network) {}
~StateConnectionConnected() {}
int get_state() {return STATE::Connected;}
void send_system_quit();
void send_system_disconnect();
void send_system_ack_sync();
void send_system_ack_probe();
void receive_system_sync(Ref<BitStream> msgin);
void receive_message(int index);
void send_message();
};
// class define state quit
class StateConnectionQuit : public StateConnectionBase
{
public:
StateConnectionQuit(NetworkConnectionCore * network) : StateConnectionBase(network) {}
~StateConnectionQuit() {}
int get_state() {return STATE::Quit;}
};
#endif

View file

@ -30,6 +30,11 @@ msg="*res://assets/Scripts/Definition/msg.gd"
[debug]
settings/stdout/verbose_stdout=true
gdscript/warnings/unused_class_variable=true
gdscript/warnings/unsafe_property_access=true
gdscript/warnings/unsafe_method_access=true
gdscript/warnings/unsafe_cast=true
gdscript/warnings/unsafe_call_argument=true
[display]