adding login on gdnative [c++]
This commit is contained in:
parent
e7ba3d0d56
commit
eba1314eb3
22 changed files with 1156 additions and 298 deletions
|
@ -31,13 +31,15 @@ scons -C godot-cpp platform=linux generate_bindings=yes custom_api_file=godot_he
|
||||||
### Build on 64bits
|
### Build on 64bits
|
||||||
|
|
||||||
```
|
```
|
||||||
scons -C gdnative platform=linux bits=64
|
scons -C gdnative platform=linux bits=64 target=debug
|
||||||
|
scons -C gdnative platform=linux bits=64 target=release
|
||||||
```
|
```
|
||||||
|
|
||||||
### Build on 32bits
|
### Build on 32bits
|
||||||
|
|
||||||
```
|
```
|
||||||
scons -C gdnative platform=linux bits=32
|
scons -C gdnative platform=linux bits=32 target=debug
|
||||||
|
scons -C gdnative platform=linux bits=64 target=release
|
||||||
```
|
```
|
||||||
|
|
||||||
## Package client khaganat
|
## Package client khaganat
|
||||||
|
|
|
@ -111,7 +111,6 @@ func _enter_tree():
|
||||||
background.self_modulate = background_color
|
background.self_modulate = background_color
|
||||||
|
|
||||||
self.add_window_part( background )
|
self.add_window_part( background )
|
||||||
print("[ui_window:3]")
|
|
||||||
# background.set_owner( self )
|
# background.set_owner( self )
|
||||||
###
|
###
|
||||||
###
|
###
|
||||||
|
|
|
@ -10,12 +10,16 @@ var _msg_data = {}
|
||||||
|
|
||||||
func open_message_xml():
|
func open_message_xml():
|
||||||
var file = File.new()
|
var file = File.new()
|
||||||
|
# Calculate MD5SUM
|
||||||
file.open("res://assets/Definition/msg.xml", File.READ)
|
file.open("res://assets/Definition/msg.xml", File.READ)
|
||||||
var content = file.get_as_text()
|
var content = file.get_as_text()
|
||||||
_msg_md5sum = content.md5_text()
|
_msg_md5sum = content.md5_text()
|
||||||
file.close()
|
file.close()
|
||||||
|
print("[res://assets/Scripts/Definition/msg.gd:open_message_xml] checksum for msg.xml:" + _msg_md5sum)
|
||||||
|
var NetworkConnexion = preload("res://networkconnexion.gdns").new()
|
||||||
|
NetworkConnexion.define_checksum_msg_xml(content.md5_buffer())
|
||||||
|
# Load XML data
|
||||||
_msg_xml.open("res://assets/Definition/msg.xml")
|
_msg_xml.open("res://assets/Definition/msg.xml")
|
||||||
print("[msg:open_message_xml] " + _msg_md5sum)
|
|
||||||
|
|
||||||
func is_correct_md5(value):
|
func is_correct_md5(value):
|
||||||
return (_msg_md5sum == value)
|
return (_msg_md5sum == value)
|
||||||
|
@ -26,6 +30,8 @@ func read_all_node():
|
||||||
var ret = _msg_xml.read()
|
var ret = _msg_xml.read()
|
||||||
var branch = ""
|
var branch = ""
|
||||||
var leaf = ""
|
var leaf = ""
|
||||||
|
var ibranch = 0
|
||||||
|
var ileaf = 0
|
||||||
while ret == OK:
|
while ret == OK:
|
||||||
#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()) )
|
#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
|
#i = 0
|
||||||
|
@ -44,7 +50,9 @@ func read_all_node():
|
||||||
if i < _msg_xml.get_attribute_count():
|
if i < _msg_xml.get_attribute_count():
|
||||||
branch = _msg_xml.get_attribute_value(i)
|
branch = _msg_xml.get_attribute_value(i)
|
||||||
#print(branch + " " + str(_msg_xml.get_node_type()))
|
#print(branch + " " + str(_msg_xml.get_node_type()))
|
||||||
_msg_data[branch] = []
|
_msg_data[branch] = {"leaf": {}, "pos": ibranch}
|
||||||
|
ibranch += 1
|
||||||
|
ileaf = 0
|
||||||
"leaf":
|
"leaf":
|
||||||
i = 0
|
i = 0
|
||||||
while i < _msg_xml.get_attribute_count() and _msg_xml.get_attribute_name(i) != "name":
|
while i < _msg_xml.get_attribute_count() and _msg_xml.get_attribute_name(i) != "name":
|
||||||
|
@ -52,21 +60,35 @@ func read_all_node():
|
||||||
if i < _msg_xml.get_attribute_count():
|
if i < _msg_xml.get_attribute_count():
|
||||||
leaf = _msg_xml.get_attribute_value(i)
|
leaf = _msg_xml.get_attribute_value(i)
|
||||||
#print(branch + ":" + leaf + str(_msg_xml.get_node_type()))
|
#print(branch + ":" + leaf + str(_msg_xml.get_node_type()))
|
||||||
_msg_data[branch].append(leaf)
|
_msg_data[branch]["leaf"][leaf] = ileaf
|
||||||
|
ileaf += 1
|
||||||
ret = _msg_xml.read()
|
ret = _msg_xml.read()
|
||||||
print("Branch:" + str(_msg_data.size()))
|
if ProjectSettings.get_setting("khaganat/debug_mode"):
|
||||||
for key in _msg_data:
|
#print("Branch:" + str(_msg_data.size()))
|
||||||
print(" " + key + ":" + str(_msg_data[key].size()))
|
var sizebranch = _msg_data.size()
|
||||||
for leaf in _msg_data[key]:
|
for key in _msg_data:
|
||||||
print(" " + key + ":" + leaf)
|
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():
|
||||||
open_message_xml()
|
open_message_xml()
|
||||||
read_all_node()
|
read_all_node()
|
||||||
print("[msg] ready")
|
print("[res://assets/Scripts/Definition/msg.gd] ready")
|
||||||
|
|
||||||
|
|
||||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||||
#func _process(delta):
|
#func _process(delta):
|
||||||
# pass
|
# pass
|
||||||
|
|
||||||
|
|
||||||
|
func read_msg(msgin):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
func write_msg(value):
|
||||||
|
pass
|
|
@ -20,292 +20,32 @@
|
||||||
|
|
||||||
extends Control
|
extends Control
|
||||||
|
|
||||||
enum TCONNECTIONSTATE {
|
|
||||||
NOTINITIALISED = 0, # nothing happened yet
|
|
||||||
NOTCONNECTED = 1, # init() called
|
|
||||||
AUTHENTICATE = 2, # connect() called, identified by the login server
|
|
||||||
LOGIN = 3, # connecting to the frontend, sending identification
|
|
||||||
SYNCHRONIZE = 4, # connection accepted by the frontend, synchronizing
|
|
||||||
CONNECTED = 5, # synchronized, connected, ready to work
|
|
||||||
PROBE = 6, # connection lost by frontend, probing for response
|
|
||||||
STALLED = 7, # server is stalled
|
|
||||||
DISCONNECT = 8, # disconnect() called, or timeout, or connection closed by frontend
|
|
||||||
QUIT = 9}
|
|
||||||
|
|
||||||
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}
|
|
||||||
|
|
||||||
const NUM_BITS_IN_LONG_ACK = 512
|
|
||||||
|
|
||||||
var _connection_state
|
|
||||||
|
|
||||||
var _socketUDP
|
|
||||||
|
|
||||||
var _user_addr
|
|
||||||
var _user_key
|
|
||||||
var _user_id
|
|
||||||
|
|
||||||
var _current_received_number
|
|
||||||
var _last_received_number
|
|
||||||
var _confirmed_received_number
|
|
||||||
|
|
||||||
var _last_ack_bit
|
|
||||||
var _ack_bit_mask
|
|
||||||
var _long_ack_bit_field
|
|
||||||
var _last_ack_in_long_ack
|
|
||||||
var _latest_sync
|
|
||||||
|
|
||||||
var _latest_probe_time
|
|
||||||
var _latest_probe
|
|
||||||
var _latest_probes
|
|
||||||
|
|
||||||
var _quit_id
|
|
||||||
var _update_time
|
|
||||||
var _queue_message_system
|
|
||||||
|
|
||||||
var _khaganat_host = "localhost"
|
|
||||||
var _khaganat_port = "47851"
|
|
||||||
|
|
||||||
onready var BitStream = preload("res://bitstream.gdns")
|
onready var BitStream = preload("res://bitstream.gdns")
|
||||||
onready var BitSet = preload("res://bitset.gdns")
|
onready var BitSet = preload("res://bitset.gdns")
|
||||||
|
onready var NetworkConnexion = preload("res://networkconnexion.gdns")
|
||||||
|
|
||||||
|
var _networkconnexion
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
_current_received_number = 0
|
_networkconnexion = NetworkConnexion.new()
|
||||||
_last_received_number = 0
|
|
||||||
_confirmed_received_number = 0
|
|
||||||
_last_ack_bit = 0
|
|
||||||
_ack_bit_mask = 0
|
|
||||||
_connection_state = TCONNECTIONSTATE.NOTINITIALISED
|
|
||||||
_socketUDP = PacketPeerUDP.new()
|
|
||||||
_queue_message_system = Array()
|
|
||||||
_long_ack_bit_field = BitSet.new()
|
|
||||||
_long_ack_bit_field.resize(512)
|
|
||||||
_last_ack_in_long_ack = 0
|
|
||||||
_latest_sync = 0
|
|
||||||
_latest_probe_time = 0
|
|
||||||
_latest_probe = 0
|
|
||||||
_latest_probes = Array()
|
|
||||||
_update_time = 0
|
|
||||||
_quit_id = 0
|
|
||||||
|
|
||||||
func send_system_login(user_addr, user_key, user_id, lang):
|
func send_system_login(host, port, user_addr, user_key, user_id, lang):
|
||||||
var msgout = BitStream.new()
|
_networkconnexion.send_system_login(host, port, user_addr, user_key, user_id, lang)
|
||||||
msgout.put_sint32(_current_received_number)
|
|
||||||
msgout.put_bool(true)
|
|
||||||
msgout.put_uint8(CLFECOMMON.SYSTEM_LOGIN_CODE)
|
|
||||||
msgout.put_string_hexa32(user_addr)
|
|
||||||
msgout.put_string_hexa32(user_key)
|
|
||||||
msgout.put_string_hexa32(user_id)
|
|
||||||
msgout.put_string(lang)
|
|
||||||
print("[net_low_level:send_system_login] Send System Login :" + msgout.show())
|
|
||||||
# To connect you need send 1st message
|
|
||||||
var res = _socketUDP.put_packet(msgout.get_data())
|
|
||||||
if ( res != OK):
|
|
||||||
print("[net_low_level:send_system_login] Error to send system login : " + str(res))
|
|
||||||
return
|
|
||||||
_connection_state = TCONNECTIONSTATE.CONNECTED
|
|
||||||
|
|
||||||
func send_system_sync():
|
|
||||||
var msgout = BitStream.new()
|
|
||||||
msgout.put_sint32(_current_received_number)
|
|
||||||
msgout.put_bool(true)
|
|
||||||
msgout.put_uint8(CLFECOMMON.SYSTEM_ACK_SYNC_CODE)
|
|
||||||
msgout.put_sint32(_last_received_number)
|
|
||||||
msgout.put_sint32(_last_ack_in_long_ack)
|
|
||||||
_long_ack_bit_field.write_serial(msgout)
|
|
||||||
msgout.put_sint32(_latest_sync)
|
|
||||||
_queue_message_system.append(msgout)
|
|
||||||
|
|
||||||
func send_system_ack_probe():
|
|
||||||
var msgout = BitStream.new()
|
|
||||||
msgout.put_sint32(_current_received_number)
|
|
||||||
msgout.put_bool(true)
|
|
||||||
msgout.put_uint8(CLFECOMMON.SYSTEM_ACK_PROBE_CODE)
|
|
||||||
msgout.put_sint32(_latest_probes.size())
|
|
||||||
for data in _latest_probes:
|
|
||||||
msgout.put_sint32(data)
|
|
||||||
_latest_probes.clear()
|
|
||||||
#_queue_message_system.append(msgout)
|
|
||||||
var res = _socketUDP.put_packet(msgout.get_data())
|
|
||||||
if ( res != OK):
|
|
||||||
print("[net_low_level:send_system_quit] Error to send system quit : " + str(res))
|
|
||||||
return
|
|
||||||
|
|
||||||
func send_system_quit():
|
func send_system_quit():
|
||||||
# TODO - check why we send quit_id
|
_networkconnexion.send_system_quit()
|
||||||
var msgout = BitStream.new()
|
|
||||||
_quit_id += 1
|
|
||||||
msgout.put_sint32(_current_received_number)
|
|
||||||
msgout.put_bool(true)
|
|
||||||
msgout.put_uint8(CLFECOMMON.SYSTEM_QUIT_CODE)
|
|
||||||
msgout.put_sint32(_quit_id)
|
|
||||||
#_queue_message_system.append(msgout)
|
|
||||||
_connection_state == TCONNECTIONSTATE.QUIT
|
|
||||||
var res = _socketUDP.put_packet(msgout.get_data())
|
|
||||||
if ( res != OK):
|
|
||||||
print("[net_low_level:send_system_quit] Error to send system quit : " + str(res))
|
|
||||||
return
|
|
||||||
|
|
||||||
func send_systemm_disconnect():
|
func send_systemm_disconnect():
|
||||||
var msgout = BitStream.new()
|
_networkconnexion.send_systemm_disconnect()
|
||||||
msgout.put_sint32(_current_received_number)
|
|
||||||
msgout.put_bool(true)
|
|
||||||
msgout.put_uint8(CLFECOMMON.SYSTEM_DISCONNECTION_CODE)
|
|
||||||
var res = _socketUDP.put_packet(msgout.get_data())
|
|
||||||
_connection_state == TCONNECTIONSTATE.QUIT
|
|
||||||
if ( res != OK):
|
|
||||||
print("[net_low_level:send_systemm_disconnect] Error to send system disconnection : " + str(res))
|
|
||||||
return
|
|
||||||
|
|
||||||
func disconnect_server():
|
func disconnect_server():
|
||||||
print("[net_low_level:disconnect_server] Disconnect")
|
_networkconnexion.disconnect_server()
|
||||||
if typeof(_socketUDP) != TYPE_NIL:
|
|
||||||
send_systemm_disconnect()
|
|
||||||
print("[net_low_level:disconnect_server] Send disconnect to server")
|
|
||||||
_socketUDP.close()
|
|
||||||
_socketUDP = null
|
|
||||||
|
|
||||||
func set_khaganat_server(host, port):
|
func connect_to_server(host, port, user_addr, user_key, user_id, lang):
|
||||||
_khaganat_host = host
|
send_system_login(host, port, user_addr, user_key, user_id, lang)
|
||||||
_khaganat_port = port
|
|
||||||
|
|
||||||
func connect_to_server(user_addr, user_key, user_id):
|
|
||||||
var connexion = load("res://assets/Scripts/Config/connexion.gd").connexion.new()
|
|
||||||
var lang = connexion.get_language()
|
|
||||||
print("[net_low_level:connect_to_server] prepare:" + str(_khaganat_host) + ":" + str(_khaganat_port))
|
|
||||||
if typeof(_socketUDP) == TYPE_NIL:
|
|
||||||
_socketUDP = PacketPeerUDP.new()
|
|
||||||
_socketUDP.set_dest_address(_khaganat_host, _khaganat_port)
|
|
||||||
send_system_login(user_addr, user_key, user_id, lang)
|
|
||||||
|
|
||||||
func decode_system_message(msgin):
|
|
||||||
var message = msgin.get_uint8()
|
|
||||||
print("[net_low_level:analyze_message_received] Message type:" + str(message) )
|
|
||||||
match message:
|
|
||||||
CLFECOMMON.SYSTEM_LOGIN_CODE:
|
|
||||||
pass
|
|
||||||
CLFECOMMON.SYSTEM_SYNC_CODE:
|
|
||||||
var hexa = preload("res://assets/Scripts/Tools/hexa.gd").new()
|
|
||||||
var synchronize = msgin.get_uint32()
|
|
||||||
var stime = msgin.get_sint64()
|
|
||||||
_latest_sync = msgin.get_uint32()
|
|
||||||
var msg_xml = msgin.get_array_uint8(16)
|
|
||||||
var database_xml = msgin.get_array_uint8(16)
|
|
||||||
print("[net_low_level:analyze_message_received] synchronize:" + str(synchronize) + " stime:" + str(stime) + " latest_sync:" + str(_latest_sync))
|
|
||||||
var num = ""
|
|
||||||
for item in msg_xml:
|
|
||||||
num += str(item) + "."
|
|
||||||
print(num)
|
|
||||||
print(hexa.ArrayIntToStringHexa(msg_xml))
|
|
||||||
num = ""
|
|
||||||
for item in database_xml:
|
|
||||||
num += str(item) + "."
|
|
||||||
print(num)
|
|
||||||
print(hexa.ArrayIntToStringHexa(database_xml))
|
|
||||||
if not msg.is_correct_md5(hexa.ArrayIntToStringHexa(msg_xml)):
|
|
||||||
print("[net_low_level:analyze_message_received] Wrong MD5 for msg.xml")
|
|
||||||
# TODO - we need quit with message error and go to login
|
|
||||||
return
|
|
||||||
send_system_sync()
|
|
||||||
CLFECOMMON.SYSTEM_STALLED_CODE:
|
|
||||||
pass
|
|
||||||
CLFECOMMON.SYSTEM_PROBE_CODE:
|
|
||||||
_latest_probe_time = _update_time
|
|
||||||
_latest_probe = msgin.get_sint32()
|
|
||||||
_latest_probes.append(_latest_probe)
|
|
||||||
send_system_ack_probe()
|
|
||||||
CLFECOMMON.SYSTEM_SERVER_DOWN_CODE:
|
|
||||||
pass
|
|
||||||
_:
|
|
||||||
print("[net_low_level:analyze_message_received] Message type unknown (" + str(message) + ")")
|
|
||||||
|
|
||||||
func decode_normal_message(msgin):
|
|
||||||
pass
|
|
||||||
|
|
||||||
func analyze_message_received(msgbytes):
|
|
||||||
# khanat-opennel-code/code/ryzom/server/src/frontend_service/fe_receive_sub.cpp:769 void CFeReceiveSub::handleReceivedMsg( CClientHost *clienthost )
|
|
||||||
_update_time = OS.get_ticks_msec()
|
|
||||||
var msgin = BitStream.new()
|
|
||||||
msgin.put_data(msgbytes)
|
|
||||||
_current_received_number = msgin.get_sint32()
|
|
||||||
var system_mode = msgin.get_bool()
|
|
||||||
if ProjectSettings.get_setting("khaganat/debug_mode"):
|
|
||||||
print("[net_low_level:analyze_message_received] Tick:" + str(_current_received_number) + ", Mode:" + str(system_mode) + ", Size:" + str(msgin.size()))
|
|
||||||
if system_mode:
|
|
||||||
print("[net_low_level:analyze_message_received] System Mode")
|
|
||||||
if _current_received_number > _last_received_number + 1:
|
|
||||||
print("[net_low_level:analyze_message_received] lost message : " + str(_last_received_number + 1 - _current_received_number))
|
|
||||||
elif _current_received_number == _last_received_number:
|
|
||||||
print("[net_low_level:analyze_message_received] Server re-send last message")
|
|
||||||
return
|
|
||||||
elif _current_received_number < _last_received_number:
|
|
||||||
print("[net_low_level:analyze_message_received] Server re-send old message")
|
|
||||||
return
|
|
||||||
var ackBool = false
|
|
||||||
var ackBit = 0
|
|
||||||
if not system_mode:
|
|
||||||
match _connection_state:
|
|
||||||
TCONNECTIONSTATE.CONNECTED:
|
|
||||||
ackBool = true
|
|
||||||
ackBit = 1
|
|
||||||
TCONNECTIONSTATE.SYNCHRONIZE:
|
|
||||||
ackBool = true
|
|
||||||
ackBit = 1
|
|
||||||
_:
|
|
||||||
ackBool = false
|
|
||||||
if _current_received_number - _last_received_number < 32:
|
|
||||||
_ack_bit_mask <<= _current_received_number - _last_received_number
|
|
||||||
_ack_bit_mask |= _last_ack_bit << (_current_received_number - _last_received_number - 1)
|
|
||||||
elif (_current_received_number - _last_received_number) == 32 and _last_ack_bit != 0:
|
|
||||||
_ack_bit_mask = 0x80000000
|
|
||||||
else:
|
|
||||||
_ack_bit_mask = 0x00000000
|
|
||||||
_last_ack_bit = ackBit
|
|
||||||
for i in range(_last_received_number + 1, _current_received_number):
|
|
||||||
_long_ack_bit_field.clear_bit(i & (NUM_BITS_IN_LONG_ACK -1))
|
|
||||||
_long_ack_bit_field.put(_current_received_number & (NUM_BITS_IN_LONG_ACK-1), ackBool)
|
|
||||||
if _last_ack_in_long_ack <= (_last_received_number - NUM_BITS_IN_LONG_ACK):
|
|
||||||
_last_ack_in_long_ack = _last_received_number - NUM_BITS_IN_LONG_ACK + 1
|
|
||||||
_last_received_number = _current_received_number
|
|
||||||
|
|
||||||
if system_mode:
|
|
||||||
decode_system_message(msgin)
|
|
||||||
else:
|
|
||||||
decode_normal_message(msgin)
|
|
||||||
|
|
||||||
func _process(delta):
|
func _process(delta):
|
||||||
if typeof(_socketUDP) == TYPE_NIL:
|
_networkconnexion.process(delta)
|
||||||
return
|
|
||||||
var max_read = 10
|
|
||||||
if _connection_state == TCONNECTIONSTATE.NOTINITIALISED:
|
|
||||||
return
|
|
||||||
if _connection_state == TCONNECTIONSTATE.NOTCONNECTED:
|
|
||||||
return
|
|
||||||
if _connection_state == TCONNECTIONSTATE.QUIT:
|
|
||||||
return
|
|
||||||
if _queue_message_system.size() > 0:
|
|
||||||
var msgout = _queue_message_system.pop_front()
|
|
||||||
if ProjectSettings.get_setting("khaganat/debug_mode"):
|
|
||||||
print("[net_low_level:_process] Send data system (" + str(msgout.size()) + ", " + msgout.show() + ")" )
|
|
||||||
_socketUDP.put_packet(msgout.get_data())
|
|
||||||
|
|
||||||
if _latest_probes.size() > 0:
|
|
||||||
send_system_ack_probe()
|
|
||||||
|
|
||||||
while _socketUDP.get_available_packet_count() > 0 and max_read > 0:
|
|
||||||
var msgbytes = _socketUDP.get_packet()
|
|
||||||
if msgbytes.size() > 0:
|
|
||||||
analyze_message_received(msgbytes)
|
|
||||||
|
|
||||||
func _exit_tree():
|
func _exit_tree():
|
||||||
print("[net_low_level] End")
|
print("[net_low_level] End")
|
||||||
|
|
|
@ -50,6 +50,7 @@ void BitStream::_register_methods()
|
||||||
|
|
||||||
register_method("show", &BitStream::show);
|
register_method("show", &BitStream::show);
|
||||||
register_method("show_detail", &BitStream::show_detail);
|
register_method("show_detail", &BitStream::show_detail);
|
||||||
|
register_method("show_counter", &BitStream::show_counter);
|
||||||
|
|
||||||
register_method("get_data", &BitStream::get_data);
|
register_method("get_data", &BitStream::get_data);
|
||||||
register_method("put_data", &BitStream::put_data);
|
register_method("put_data", &BitStream::put_data);
|
||||||
|
@ -67,10 +68,15 @@ void BitStream::_register_methods()
|
||||||
register_method("get_array_uint8", &BitStream::get_array_uint8);
|
register_method("get_array_uint8", &BitStream::get_array_uint8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BitStream::clear()
|
||||||
|
{
|
||||||
|
this->_pos = 0;
|
||||||
|
this->_read = 0;
|
||||||
|
}
|
||||||
|
|
||||||
BitStream::BitStream()
|
BitStream::BitStream()
|
||||||
{
|
{
|
||||||
this->_pos = 0;
|
clear();
|
||||||
this->_read = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BitStream::~BitStream()
|
BitStream::~BitStream()
|
||||||
|
@ -313,6 +319,13 @@ String BitStream::show_detail()
|
||||||
return "[size:" + strsize + ", pos:" + strpos + "]" + ret ;
|
return "[size:" + strsize + ", pos:" + strpos + "]" + ret ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String BitStream::show_counter()
|
||||||
|
{
|
||||||
|
String ret = "[" + String::num_int64(this->_read) + " / " + String::num_int64(this->_pos) + "]";
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
PoolByteArray BitStream::get_data()
|
PoolByteArray BitStream::get_data()
|
||||||
{
|
{
|
||||||
return this->_data;
|
return this->_data;
|
||||||
|
@ -441,4 +454,4 @@ PoolByteArray BitStream::get_array_uint8(uint32_t length)
|
||||||
--length;
|
--length;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,8 @@ private:
|
||||||
public:
|
public:
|
||||||
static void _register_methods();
|
static void _register_methods();
|
||||||
|
|
||||||
|
void clear();
|
||||||
|
|
||||||
BitStream();
|
BitStream();
|
||||||
~BitStream();
|
~BitStream();
|
||||||
|
|
||||||
|
@ -61,6 +63,7 @@ public:
|
||||||
|
|
||||||
String show();
|
String show();
|
||||||
String show_detail();
|
String show_detail();
|
||||||
|
String show_counter();
|
||||||
|
|
||||||
PoolByteArray get_data();
|
PoolByteArray get_data();
|
||||||
void put_data(PoolByteArray value);
|
void put_data(PoolByteArray value);
|
||||||
|
|
42
gdnative/src/clfecommon.h
Normal file
42
gdnative/src/clfecommon.h
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
Header CLFECOMMON : message send by 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/>.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CLFECOMMON_H
|
||||||
|
#define CLFECOMMON_H
|
||||||
|
|
||||||
|
namespace godot {
|
||||||
|
|
||||||
|
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
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // CLFECOMMON_H
|
|
@ -6,8 +6,8 @@
|
||||||
|
|
||||||
namespace godot {
|
namespace godot {
|
||||||
|
|
||||||
class Crypt : public Reference {
|
class Crypt : public Object {
|
||||||
GODOT_CLASS(Crypt, Reference)
|
GODOT_CLASS(Crypt, Object)
|
||||||
public:
|
public:
|
||||||
static void _register_methods();
|
static void _register_methods();
|
||||||
|
|
||||||
|
|
|
@ -21,22 +21,25 @@
|
||||||
#include "bitstream.h"
|
#include "bitstream.h"
|
||||||
#include "bitset.h"
|
#include "bitset.h"
|
||||||
#include "crypt.h"
|
#include "crypt.h"
|
||||||
|
#include "network_connection.h"
|
||||||
|
|
||||||
/** GDNative Initialize **/
|
/** GDNative Initialize **/
|
||||||
extern "C" void GDN_EXPORT godot_gdnative_init(godot_gdnative_init_options *o) {
|
extern "C" void GDN_EXPORT godot_gdnative_init(godot_gdnative_init_options *o) {
|
||||||
godot::Godot::gdnative_init(o);
|
godot::Godot::gdnative_init(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** GDNative Terminate **/
|
/** GDNative Terminate **/
|
||||||
extern "C" void GDN_EXPORT godot_gdnative_terminate(godot_gdnative_terminate_options *o) {
|
extern "C" void GDN_EXPORT godot_gdnative_terminate(godot_gdnative_terminate_options *o) {
|
||||||
godot::Godot::gdnative_terminate(o);
|
terminate_network_connection();
|
||||||
|
godot::Godot::gdnative_terminate(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** NativeScript Initialize **/
|
/** NativeScript Initialize **/
|
||||||
extern "C" void GDN_EXPORT godot_nativescript_init(void *handle) {
|
extern "C" void GDN_EXPORT godot_nativescript_init(void *handle) {
|
||||||
godot::Godot::nativescript_init(handle);
|
godot::Godot::nativescript_init(handle);
|
||||||
|
|
||||||
godot::register_class<godot::BitStream>();
|
godot::register_class<godot::BitStream>();
|
||||||
godot::register_class<godot::BitSet>();
|
godot::register_class<godot::BitSet>();
|
||||||
godot::register_class<godot::Crypt>();
|
godot::register_class<godot::Crypt>();
|
||||||
|
godot::register_class<godot::NetworkConnection>();
|
||||||
}
|
}
|
||||||
|
|
93
gdnative/src/network_connection.cpp
Normal file
93
gdnative/src/network_connection.cpp
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
/*
|
||||||
|
Library to present all functions of NetworkConnectionCore (network)
|
||||||
|
|
||||||
|
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 <Godot.hpp>
|
||||||
|
#include "network_connection.h"
|
||||||
|
#include "bitstream.h"
|
||||||
|
#include "network_connection_core.h"
|
||||||
|
|
||||||
|
using namespace godot;
|
||||||
|
|
||||||
|
NetworkConnectionCore *NetworkConnectionCore::singleton = NULL;
|
||||||
|
|
||||||
|
void NetworkConnection::_register_methods()
|
||||||
|
{
|
||||||
|
register_method("define_checksum_msg_xml", &NetworkConnection::define_checksum_msg_xml);
|
||||||
|
register_method("define_socket_udp", &NetworkConnection::define_socket_udp);
|
||||||
|
register_method("send_system_login", &NetworkConnection::send_system_login);
|
||||||
|
register_method("send_system_disconnect", &NetworkConnection::send_system_disconnect);
|
||||||
|
register_method("send_system_quit", &NetworkConnection::send_system_quit);
|
||||||
|
register_method("disconnect_server", &NetworkConnection::disconnect_server);
|
||||||
|
register_method("process", &NetworkConnection::process);
|
||||||
|
register_method("get_state", &NetworkConnection::get_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkConnection::NetworkConnection()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkConnection::~NetworkConnection()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int NetworkConnection::get_state()
|
||||||
|
{
|
||||||
|
return NetworkConnectionCore::get_singleton()->get_state();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkConnection::define_checksum_msg_xml(Array checksum_msg_xml)
|
||||||
|
{
|
||||||
|
NetworkConnectionCore::get_singleton()->define_checksum_msg_xml(checksum_msg_xml);
|
||||||
|
}
|
||||||
|
void NetworkConnection::define_socket_udp(PacketPeerUDP * socketUDP)
|
||||||
|
{
|
||||||
|
NetworkConnectionCore::get_singleton()->define_socket_udp(socketUDP);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkConnection::send_system_login(String host, int64_t port, String user_addr, String user_key, String user_id, String lang)
|
||||||
|
{
|
||||||
|
NetworkConnectionCore::get_singleton()->send_system_login(host, port, user_addr, user_key, user_id, lang);
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkConnection::process(int delta)
|
||||||
|
{
|
||||||
|
NetworkConnectionCore::get_singleton()->process(delta);
|
||||||
|
}
|
||||||
|
|
||||||
|
void terminate_network_connection()
|
||||||
|
{
|
||||||
|
NetworkConnectionCore::get_singleton()->terminate_connexion();
|
||||||
|
}
|
62
gdnative/src/network_connection.h
Normal file
62
gdnative/src/network_connection.h
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
/*
|
||||||
|
Header NetworkConnection
|
||||||
|
|
||||||
|
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_CONNECTION_H
|
||||||
|
#define NETWORK_CONNECTION_H
|
||||||
|
|
||||||
|
#include <Godot.hpp>
|
||||||
|
#include <gen/PacketPeerUDP.hpp>
|
||||||
|
#include <Reference.hpp>
|
||||||
|
#include "bitstream.h"
|
||||||
|
#include "clfecommon.h"
|
||||||
|
#include "store_message.h"
|
||||||
|
#include "network_connection_core.h"
|
||||||
|
|
||||||
|
namespace godot {
|
||||||
|
|
||||||
|
class NetworkConnection : public Object {
|
||||||
|
GODOT_CLASS(NetworkConnection, Object)
|
||||||
|
private:
|
||||||
|
static void _bind_methods();
|
||||||
|
public:
|
||||||
|
NetworkConnection();
|
||||||
|
~NetworkConnection();
|
||||||
|
|
||||||
|
static void _register_methods();
|
||||||
|
|
||||||
|
/* _init must exist as it is called by Godot */
|
||||||
|
void _init() {};
|
||||||
|
|
||||||
|
void define_checksum_msg_xml(Array checksum_msg_xml);
|
||||||
|
void define_socket_udp(PacketPeerUDP * socketUDP); // Not necessary, but you can define network directly on GdScript
|
||||||
|
void send_system_login(String host, int64_t port, String user_addr, String user_key, String user_id, String lang);
|
||||||
|
void send_system_disconnect();
|
||||||
|
void send_system_quit();
|
||||||
|
void disconnect_server();
|
||||||
|
void process(int delta);
|
||||||
|
int get_state();
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void terminate_network_connection();
|
||||||
|
|
||||||
|
|
||||||
|
#endif // NETWORK_CONNECTION_H
|
482
gdnative/src/network_connection_core.cpp
Normal file
482
gdnative/src/network_connection_core.cpp
Normal file
|
@ -0,0 +1,482 @@
|
||||||
|
/*
|
||||||
|
Library to manage network
|
||||||
|
|
||||||
|
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/>.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define DEBUG_ENABLED
|
||||||
|
|
||||||
|
#include <Godot.hpp>
|
||||||
|
#include <core/Defs.hpp>
|
||||||
|
#include <gen/PacketPeerUDP.hpp>
|
||||||
|
|
||||||
|
#include "tools.h"
|
||||||
|
#include "bitset.h"
|
||||||
|
#include "bitstream.h"
|
||||||
|
#include "network_connection_core.h"
|
||||||
|
#include "state.h"
|
||||||
|
|
||||||
|
using namespace godot;
|
||||||
|
|
||||||
|
NetworkConnectionCore *NetworkConnectionCore::get_singleton()
|
||||||
|
{
|
||||||
|
if ( NetworkConnectionCore::singleton == NULL )
|
||||||
|
NetworkConnectionCore::singleton = new NetworkConnectionCore();
|
||||||
|
return NetworkConnectionCore::singleton;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkConnectionCore::NetworkConnectionCore()
|
||||||
|
{
|
||||||
|
this->_socketUDP = NULL;
|
||||||
|
this->_state = STATE::NotInitialised ;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkConnectionCore::~NetworkConnectionCore()
|
||||||
|
{
|
||||||
|
NetworkConnectionCore::singleton = NULL;
|
||||||
|
this->_state = STATE::NotInitialised ;
|
||||||
|
}
|
||||||
|
|
||||||
|
int NetworkConnectionCore::get_state()
|
||||||
|
{
|
||||||
|
return this->_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkConnectionCore::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()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkConnectionCore::define_socket_udp(PacketPeerUDP * socketUDP)
|
||||||
|
{
|
||||||
|
// Use if you define PacketPeerUDP on other script
|
||||||
|
if ( this->_socketUDP == NULL)
|
||||||
|
this->_socketUDP = socketUDP;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkConnectionCore::autodefine_socket_udp()
|
||||||
|
{
|
||||||
|
// Create socket udp if not defined (If you don't use define_socket_udp)
|
||||||
|
if ( this->_socketUDP == NULL)
|
||||||
|
{
|
||||||
|
PacketPeerUDP::___init_method_bindings();
|
||||||
|
this->_socketUDP = PacketPeerUDP::_new();
|
||||||
|
if ( this->_socketUDP == NULL)
|
||||||
|
throw "Failed to open network";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkConnectionCore::send_system_login(String host, int64_t port, String user_addr, String user_key, String user_id, String lang)
|
||||||
|
{
|
||||||
|
// Configure socket UDP
|
||||||
|
this->autodefine_socket_udp();
|
||||||
|
if ( this->_state != STATE::NotInitialised )
|
||||||
|
{
|
||||||
|
DEBUG_PRINT("Close old network socket");
|
||||||
|
this->_socketUDP->close();
|
||||||
|
}
|
||||||
|
|
||||||
|
INFO_PRINT("Connect to " + host + ":" + itos(port));
|
||||||
|
this->_socketUDP->set_dest_address(host, port);
|
||||||
|
// Open connection and send ID
|
||||||
|
|
||||||
|
BitStream msgout;
|
||||||
|
msgout.put_sint32(_current_received_number);
|
||||||
|
msgout.put_bool(true);
|
||||||
|
msgout.put_uint8(CLFECOMMON::SYSTEM_LOGIN_CODE);
|
||||||
|
msgout.put_string_hexa32(user_addr);
|
||||||
|
msgout.put_string_hexa32(user_key);
|
||||||
|
msgout.put_string_hexa32(user_id);
|
||||||
|
msgout.put_string(lang);
|
||||||
|
godot::Error ret;
|
||||||
|
ret = this->_socketUDP->put_packet(msgout.get_data());
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
INFO_PRINT("Connected to khganat");
|
||||||
|
this->_state = STATE::Connected;
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkConnectionCore::send_system_quit()
|
||||||
|
{
|
||||||
|
// TODO - check why we send quit_id
|
||||||
|
if ( this->_state != STATE::Connected && this->_state != STATE::ForceSynchronize )
|
||||||
|
return;
|
||||||
|
DEBUG_PRINT("send quit to server");
|
||||||
|
BitStream msgout;
|
||||||
|
msgout.put_sint32(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(msgout.get_data()) != Error::OK )
|
||||||
|
{
|
||||||
|
ERR_PRINT("Error to send disconnect");
|
||||||
|
}
|
||||||
|
this->_state = STATE::Quit;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkConnectionCore::send_system_disconnect()
|
||||||
|
{
|
||||||
|
if ( this->_state != STATE::Connected && this->_state != STATE::ForceSynchronize )
|
||||||
|
return;
|
||||||
|
DEBUG_PRINT("send disconnect to server");
|
||||||
|
BitStream msgout;
|
||||||
|
msgout.put_sint32(this->_current_received_number);
|
||||||
|
msgout.put_bool(true);
|
||||||
|
msgout.put_uint8(CLFECOMMON::SYSTEM_DISCONNECTION_CODE);
|
||||||
|
|
||||||
|
if ( this->_socketUDP->put_packet(msgout.get_data()) != Error::OK )
|
||||||
|
{
|
||||||
|
ERR_PRINT("Error to send disconnect");
|
||||||
|
}
|
||||||
|
this->_socketUDP->close();
|
||||||
|
this->_state = STATE::Disconnect;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkConnectionCore::send_system_ack_probe()
|
||||||
|
{
|
||||||
|
// 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;
|
||||||
|
int max = this->_latest_probes.size();
|
||||||
|
if (max == 0 )
|
||||||
|
return;
|
||||||
|
if (this->_state == STATE::ForceSynchronize && max < 5)
|
||||||
|
return;
|
||||||
|
DEBUG_PRINT("send system ACK PROBE to server");
|
||||||
|
BitStream msgout;
|
||||||
|
msgout.put_sint32(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 )
|
||||||
|
{
|
||||||
|
//DEBUG_PRINT("i:" + itos(i));
|
||||||
|
int data = this->_latest_probes[i];
|
||||||
|
//DEBUG_PRINT("data:" + itos(data));
|
||||||
|
msgout.put_sint32(data);
|
||||||
|
//DEBUG_PRINT("updated");
|
||||||
|
}
|
||||||
|
if (this->_socketUDP->put_packet(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::disconnect_server()
|
||||||
|
{
|
||||||
|
if (this->_state != STATE::Connected && this->_state != STATE::ForceSynchronize)
|
||||||
|
return;
|
||||||
|
send_system_disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkConnectionCore::decode_system_message(BitStream *msgin)
|
||||||
|
{
|
||||||
|
int message = msgin->get_uint8();
|
||||||
|
switch (message)
|
||||||
|
{
|
||||||
|
case CLFECOMMON::SYSTEM_LOGIN_CODE:
|
||||||
|
DEBUG_PRINT("SYSTEM_LOGIN_CODE");
|
||||||
|
break;
|
||||||
|
case CLFECOMMON::SYSTEM_SYNC_CODE:
|
||||||
|
this->receive_system_sync(msgin);
|
||||||
|
break;
|
||||||
|
case CLFECOMMON::SYSTEM_STALLED_CODE:
|
||||||
|
DEBUG_PRINT("SYSTEM_STALLED_CODE");
|
||||||
|
break;
|
||||||
|
case CLFECOMMON::SYSTEM_SERVER_DOWN_CODE:
|
||||||
|
DEBUG_PRINT("SYSTEM_SERVER_DOWN_CODE");
|
||||||
|
break;
|
||||||
|
case CLFECOMMON::SYSTEM_PROBE_CODE:
|
||||||
|
this->receive_system_probe(msgin);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ERR_PRINT("Received unknown message [" + itos(message) + "]");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkConnectionCore::decode_normal_message(BitStream *msgin)
|
||||||
|
{
|
||||||
|
DEBUG_PRINT("Decode normal message");
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkConnectionCore::receive_system_sync(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);
|
||||||
|
|
||||||
|
if ( msg_xml.size() != this->_checksum_msg_xml.size() )
|
||||||
|
{
|
||||||
|
valide = false;
|
||||||
|
DEBUG_PRINT("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;
|
||||||
|
DEBUG_PRINT("MSG XML is incorrect (pos:" + itos(i) +")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( valide == true )
|
||||||
|
DEBUG_PRINT("MSG XML is correct");
|
||||||
|
else
|
||||||
|
DEBUG_PRINT("MSG.XML is wrong");
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
self._Synchronize = msg.readUint32('Synchronize')
|
||||||
|
stime = msg.readSint64('stime')
|
||||||
|
self._LatestSync = msg.readUint32('LatestSync')
|
||||||
|
logging.getLogger(LOGGER).debug("%d %d %d" %(self._Synchronize, stime, self._LatestSync))
|
||||||
|
# khanat-opennel-code/code/ryzom/client/src/network_connection.cpp : void CNetworkConnection::receiveSystemSync(CBitMemStream &msgin)
|
||||||
|
MsgData = msg.readArrayUint8(16, 'MsgData')
|
||||||
|
DatabaseData = msg.readArrayUint8(16, 'DatabaseData')
|
||||||
|
logging.getLogger(LOGGER).debug("MsgData:" + str(MsgData))
|
||||||
|
logging.getLogger(LOGGER).debug("DatabaseData:" + str(DatabaseData))
|
||||||
|
md5Msg = bytes(MsgData)
|
||||||
|
md5Database = bytes(DatabaseData)
|
||||||
|
if md5Msg == self._MsgXmlMD5:
|
||||||
|
logging.getLogger(LOGGER).info("Check MD5 msg.xml : OK")
|
||||||
|
else:
|
||||||
|
logging.getLogger(LOGGER).error("Check MD5 msg.xml : KO")
|
||||||
|
if md5Database == self._DatabaseXmlMD5:
|
||||||
|
logging.getLogger(LOGGER).info("Check MD5 database.xml : OK")
|
||||||
|
else:
|
||||||
|
logging.getLogger(LOGGER).error("Check MD5 database.xml : KO")
|
||||||
|
logging.getLogger(LOGGER).debug("Msg Received:" + msg.showAllData())
|
||||||
|
self._MsPerTick = 100
|
||||||
|
self._CurrentServerTick = self._Synchronize + self._CurrentReceivedNumber + 2
|
||||||
|
self._CurrentClientTick = self._CurrentServerTick - ( self._LCT + self._MsPerTick ) / self._MsPerTick
|
||||||
|
self._CurrentClientTime = self._UpdateTime - (self._LCT + self._MsPerTick)
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkConnectionCore::receive_system_probe(BitStream * msgin)
|
||||||
|
{
|
||||||
|
DEBUG_PRINT("SYSTEM_PROBE_CODE size:" + itos(this->_latest_probes.size()));
|
||||||
|
this->_latest_probes.append(msgin->get_sint32());
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkConnectionCore::wait_resynchronize(int32_t current_received_number, 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:
|
||||||
|
DEBUG_PRINT("SYSTEM_LOGIN_CODE");
|
||||||
|
break;
|
||||||
|
case CLFECOMMON::SYSTEM_SYNC_CODE:
|
||||||
|
DEBUG_PRINT("SYSTEM_SYNC_CODE");
|
||||||
|
break;
|
||||||
|
case CLFECOMMON::SYSTEM_STALLED_CODE:
|
||||||
|
DEBUG_PRINT("SYSTEM_STALLED_CODE");
|
||||||
|
break;
|
||||||
|
case CLFECOMMON::SYSTEM_SERVER_DOWN_CODE:
|
||||||
|
DEBUG_PRINT("SYSTEM_SERVER_DOWN_CODE");
|
||||||
|
break;
|
||||||
|
case CLFECOMMON::SYSTEM_PROBE_CODE:
|
||||||
|
this->receive_system_probe(msgin);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ERR_PRINT("Received unknown message [" + itos(message) + "]");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this->_last_received_number = current_received_number;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkConnectionCore::analyze_message_receieved(int32_t current_received_number, BitStream * msgin)
|
||||||
|
{
|
||||||
|
bool system_mode;
|
||||||
|
bool ackBool = false;
|
||||||
|
int ackBit = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
this->_current_received_number = current_received_number;
|
||||||
|
system_mode = msgin->get_bool();
|
||||||
|
if ( system_mode == true )
|
||||||
|
{
|
||||||
|
INFO_PRINT("Received system message");
|
||||||
|
if (this->_current_received_number == this->_last_received_number + 1)
|
||||||
|
{
|
||||||
|
INFO_PRINT("Received message");
|
||||||
|
}
|
||||||
|
else if (this->_current_received_number < this->_last_received_number + 1)
|
||||||
|
{
|
||||||
|
INFO_PRINT("Received old message");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (this->_current_received_number > this->_last_received_number + 1)
|
||||||
|
{
|
||||||
|
INFO_PRINT("Received message in future (lost some message)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
INFO_PRINT("Received normal message");
|
||||||
|
}
|
||||||
|
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) );
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
{
|
||||||
|
int pos = this->queue.put_msgbytes(msgbytes);
|
||||||
|
|
||||||
|
BitStream * msgin = this->queue.get_msg(pos);
|
||||||
|
int32_t current_received_number = this->queue.get_received_number(pos);
|
||||||
|
/// 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);
|
||||||
|
}
|
||||||
|
else if ( current_received_number - this->_last_received_number <= 0 ) // Received old message
|
||||||
|
{
|
||||||
|
INFO_PRINT("current_received_number : " + itos(current_received_number) + " / queue size : " + itos(this->queue.length()));
|
||||||
|
this->queue.erase(pos);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if ( this->_last_received_number + 1 == current_received_number ) // Received next message
|
||||||
|
{
|
||||||
|
INFO_PRINT("current_received_number : " + itos(current_received_number) + " / queue size : " + itos(this->queue.length()));
|
||||||
|
analyze_message_receieved(current_received_number, msgin);
|
||||||
|
this->queue.erase(pos);
|
||||||
|
}
|
||||||
|
else // Received new message (but missing some message between) -> go to queue and cross finger to received the next message (for _last_received_number)
|
||||||
|
{
|
||||||
|
INFO_PRINT("current_received_number : " + itos(current_received_number) + " / queue size : " + itos(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();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkConnectionCore::process(int delta)
|
||||||
|
{
|
||||||
|
if (this->_state != STATE::Connected && this->_state != STATE::ForceSynchronize)
|
||||||
|
return;
|
||||||
|
//INFO_PRINT( "Process - delta : " + itos(delta));
|
||||||
|
for(int i = 0; (this->_socketUDP->get_available_packet_count() > 0) && (i < MAX_LOOP_READ_BY_STEP) ; ++i)
|
||||||
|
{
|
||||||
|
PoolByteArray msgbytes ;
|
||||||
|
msgbytes = this->_socketUDP->get_packet();
|
||||||
|
DEBUG_PRINT("Size msg received : " + itos(msgbytes.size()) );
|
||||||
|
store_message_received(msgbytes);
|
||||||
|
}
|
||||||
|
send_message();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkConnectionCore::terminate_connexion()
|
||||||
|
{
|
||||||
|
DEBUG_PRINT("Terminate network connexion");
|
||||||
|
if ( this->_socketUDP == NULL )
|
||||||
|
return;
|
||||||
|
delete this-> _socketUDP;
|
||||||
|
this->_socketUDP = NULL;
|
||||||
|
}
|
88
gdnative/src/network_connection_core.h
Normal file
88
gdnative/src/network_connection_core.h
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
/*
|
||||||
|
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 NETWORK_CONNECTION_CORE_H
|
||||||
|
#define NETWORK_CONNECTION_CORE_H
|
||||||
|
|
||||||
|
#include <Godot.hpp>
|
||||||
|
#include <gen/PacketPeerUDP.hpp>
|
||||||
|
#include "bitset.h"
|
||||||
|
#include "bitstream.h"
|
||||||
|
#include "clfecommon.h"
|
||||||
|
#include "store_message.h"
|
||||||
|
#include "state.h"
|
||||||
|
|
||||||
|
#define MAX_LOOP_READ_BY_STEP 10
|
||||||
|
#define NUM_BITS_IN_LONG_ACK 512
|
||||||
|
|
||||||
|
namespace godot {
|
||||||
|
|
||||||
|
class NetworkConnectionCore : public Object {
|
||||||
|
GODOT_CLASS(NetworkConnectionCore, Object)
|
||||||
|
private:
|
||||||
|
static NetworkConnectionCore *singleton;
|
||||||
|
|
||||||
|
bool _force_resynchronize;
|
||||||
|
STATE _state;
|
||||||
|
PacketPeerUDP * _socketUDP;
|
||||||
|
int32_t _current_received_number;
|
||||||
|
int32_t _last_received_number;
|
||||||
|
int32_t _quit_id;
|
||||||
|
BitSet _long_ack_bit_field;
|
||||||
|
Array _latest_probes;
|
||||||
|
Array _checksum_msg_xml;
|
||||||
|
uint32_t _ack_bit_mask;
|
||||||
|
int32_t _last_ack_bit;
|
||||||
|
int32_t _last_ack_in_long_ack;
|
||||||
|
StoreMessage queue;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static NetworkConnectionCore * get_singleton();
|
||||||
|
|
||||||
|
NetworkConnectionCore();
|
||||||
|
~NetworkConnectionCore();
|
||||||
|
|
||||||
|
int get_state();
|
||||||
|
|
||||||
|
void define_checksum_msg_xml(Array & checksum_msg_xml);
|
||||||
|
|
||||||
|
void define_socket_udp(PacketPeerUDP * socketUDP);
|
||||||
|
void autodefine_socket_udp();
|
||||||
|
void send_system_login(String host, int64_t port, String user_addr, String user_key, String user_id, String lang);
|
||||||
|
void send_system_disconnect();
|
||||||
|
void send_system_quit();
|
||||||
|
void disconnect_server();
|
||||||
|
void send_system_ack_probe();
|
||||||
|
void decode_system_message(BitStream *msgin);
|
||||||
|
void decode_normal_message(BitStream *msgin);
|
||||||
|
void receive_system_sync(BitStream * msgin);
|
||||||
|
void receive_system_probe(BitStream * msgin);
|
||||||
|
void wait_resynchronize(int32_t current_received_number, BitStream * msgin);
|
||||||
|
void analyze_message_receieved(int32_t, BitStream *msgin);
|
||||||
|
void store_message_received(PoolByteArray & msgbytes);
|
||||||
|
void send_message();
|
||||||
|
void process(int delta);
|
||||||
|
bool connected();
|
||||||
|
void terminate_connexion();
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
38
gdnative/src/state.h
Normal file
38
gdnative/src/state.h
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
Header STATE : to know state of client
|
||||||
|
|
||||||
|
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_H
|
||||||
|
#define STATE_H
|
||||||
|
|
||||||
|
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
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // STATE_H
|
127
gdnative/src/store_message.cpp
Normal file
127
gdnative/src/store_message.cpp
Normal file
|
@ -0,0 +1,127 @@
|
||||||
|
/*
|
||||||
|
|
||||||
|
StoreMessage : class to manage packet received by khaganat
|
||||||
|
If we received message with bad order, with this class we can manage (with limit storage)
|
||||||
|
|
||||||
|
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 <Godot.hpp>
|
||||||
|
#include <core/Defs.hpp>
|
||||||
|
|
||||||
|
#include "bitstream.h"
|
||||||
|
#include "tools.h"
|
||||||
|
#include "store_message.h"
|
||||||
|
|
||||||
|
using namespace godot;
|
||||||
|
|
||||||
|
StoreMessage::StoreMessage()
|
||||||
|
{
|
||||||
|
this->clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
StoreMessage::~StoreMessage()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void StoreMessage::clear()
|
||||||
|
{
|
||||||
|
for(int i = 0 ; i < SIZE_QUEUE_MESSAGE ; ++i )
|
||||||
|
{
|
||||||
|
//this->_empty[i] = true;
|
||||||
|
this->_received_number[i] = 0;
|
||||||
|
this->_msgin[i].clear();
|
||||||
|
}
|
||||||
|
this->_size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int StoreMessage::length()
|
||||||
|
{
|
||||||
|
return this->_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
int StoreMessage::put_msgbytes(PoolByteArray & msgbytes)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
int ii ;
|
||||||
|
|
||||||
|
//while((this->_empty[i] != true)&&(i < SIZE_QUEUE_MESSAGE))
|
||||||
|
while((i < SIZE_QUEUE_MESSAGE)&&(this->_msgin[i].size_data() != 0))
|
||||||
|
++i;
|
||||||
|
|
||||||
|
if(i >= SIZE_QUEUE_MESSAGE) // Out of memory
|
||||||
|
{
|
||||||
|
ERR_PRINT("Network queue is full (" + itos(i) + " / " + itos(SIZE_QUEUE_MESSAGE) + ")");
|
||||||
|
throw "Out of memory";
|
||||||
|
}
|
||||||
|
//INFO_PRINT("-> i:" + itos(i) + "/" + itos(this->_size) + " State:" + itos(this->_msgin[i].size_data()) + " num:" + itos(this->_received_number[i]));
|
||||||
|
//INFO_PRINT("i:" + itos(i) + " / " + itos(SIZE_QUEUE_MESSAGE) );
|
||||||
|
this->_msgin[i].put_data(msgbytes);
|
||||||
|
int32_t current_received_number = this->_msgin[i].get_sint32();
|
||||||
|
this->_received_number[i] = current_received_number;
|
||||||
|
|
||||||
|
// Check we don't have other message with same _received_number (also remove it)
|
||||||
|
ii = i + 1;
|
||||||
|
while(ii < SIZE_QUEUE_MESSAGE)
|
||||||
|
{
|
||||||
|
if ( this->_received_number[ii] == current_received_number)
|
||||||
|
this->erase(ii);
|
||||||
|
++ii;
|
||||||
|
}
|
||||||
|
this->_size ++;
|
||||||
|
/*
|
||||||
|
for(int ii = 0 ; ii < SIZE_QUEUE_MESSAGE ; ++ii)
|
||||||
|
{
|
||||||
|
INFO_PRINT(itos(ii) + ") i:" + itos(i) + "/" + itos(this->_size) + " State:" + itos(this->_msgin[ii].size_data()) + " num:" + itos(this->_received_number[ii]));
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
BitStream * StoreMessage::get_msg(int pos)
|
||||||
|
{
|
||||||
|
if ( pos >= SIZE_QUEUE_MESSAGE )
|
||||||
|
{
|
||||||
|
ERR_PRINT("Try to get data out of memory");
|
||||||
|
throw "Out of memory";
|
||||||
|
}
|
||||||
|
return & this->_msgin[pos];
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t StoreMessage::get_received_number(int pos)
|
||||||
|
{
|
||||||
|
if ( pos >= SIZE_QUEUE_MESSAGE )
|
||||||
|
{
|
||||||
|
ERR_PRINT("Try to get data out of memory");
|
||||||
|
throw "Out of memory";
|
||||||
|
}
|
||||||
|
return this->_received_number[pos];
|
||||||
|
}
|
||||||
|
|
||||||
|
void StoreMessage::erase(int pos)
|
||||||
|
{
|
||||||
|
if ( pos >= SIZE_QUEUE_MESSAGE )
|
||||||
|
{
|
||||||
|
ERR_PRINT("Try to erase data out of memory");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//this->_empty[pos] = true;
|
||||||
|
this->_received_number[pos] = 0;
|
||||||
|
this->_msgin[pos].clear();
|
||||||
|
this->_size -- ;
|
||||||
|
}
|
47
gdnative/src/store_message.h
Normal file
47
gdnative/src/store_message.h
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
Header StoreMessage : message send by 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/>.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef STORE_MESSAGE_H
|
||||||
|
#define STORE_MESSAGE_H
|
||||||
|
|
||||||
|
#define SIZE_QUEUE_MESSAGE 6
|
||||||
|
|
||||||
|
namespace godot {
|
||||||
|
|
||||||
|
class StoreMessage
|
||||||
|
{
|
||||||
|
// bool _empty[SIZE_QUEUE_MESSAGE];
|
||||||
|
int32_t _received_number[SIZE_QUEUE_MESSAGE];
|
||||||
|
BitStream _msgin[SIZE_QUEUE_MESSAGE];
|
||||||
|
int _size;
|
||||||
|
public:
|
||||||
|
StoreMessage();
|
||||||
|
~StoreMessage();
|
||||||
|
void clear();
|
||||||
|
int length();
|
||||||
|
int put_msgbytes(PoolByteArray & msgbytes);
|
||||||
|
BitStream * get_msg(int pos);
|
||||||
|
int32_t get_received_number(int pos);
|
||||||
|
void erase(int pos);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // STORE_MESSAGE_H
|
29
gdnative/src/tools.cpp
Normal file
29
gdnative/src/tools.cpp
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
|
||||||
|
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 <Godot.hpp>
|
||||||
|
#include <core/Defs.hpp>
|
||||||
|
#include "tools.h"
|
||||||
|
|
||||||
|
using namespace godot;
|
||||||
|
|
||||||
|
String godot::itos(int64_t p_val)
|
||||||
|
{
|
||||||
|
return String::num_int64(p_val);
|
||||||
|
}
|
44
gdnative/src/tools.h
Normal file
44
gdnative/src/tools.h
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
Header Tools
|
||||||
|
|
||||||
|
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 TOOLS_H
|
||||||
|
#define TOOLS_H
|
||||||
|
|
||||||
|
#include <Godot.hpp>
|
||||||
|
|
||||||
|
namespace godot {
|
||||||
|
|
||||||
|
String itos(int64_t p_val);
|
||||||
|
|
||||||
|
#define INFO_PRINT(msg) Godot::print( String(__FUNCTION__) + ":" + String(__FILE__) + ":" + itos( __LINE__) + " " + String(msg))
|
||||||
|
|
||||||
|
#ifdef DEBUG_ENABLED
|
||||||
|
|
||||||
|
#define DEBUG_PRINT(msg) Godot::print( String(__FUNCTION__) + ":" + String(__FILE__) + ":" + itos( __LINE__) + " " + String(msg))
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define DEBUG_PRINT(msg)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // STORE_MESSAGE_H
|
|
@ -14,7 +14,7 @@ func _ready():
|
||||||
|
|
||||||
func test_resize():
|
func test_resize():
|
||||||
var bitset = preload("res://bitset.gdns").new()
|
var bitset = preload("res://bitset.gdns").new()
|
||||||
print ("[bitset:test_init]")
|
print ("[bitset:test_resize]")
|
||||||
bitset.resize(1024)
|
bitset.resize(1024)
|
||||||
|
|
||||||
func test_put():
|
func test_put():
|
||||||
|
@ -33,9 +33,20 @@ func test_put():
|
||||||
#print ("[bitset:test_init] " + bitset.show())
|
#print ("[bitset:test_init] " + bitset.show())
|
||||||
assert( bitset.show() == "0000000000000000000000000000010000000000000000000000000000000000001000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
|
assert( bitset.show() == "0000000000000000000000000000010000000000000000000000000000000000001000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
|
||||||
|
|
||||||
|
func test_alloc():
|
||||||
|
var BitSet = preload("res://bitset.gdns")
|
||||||
|
print ("[bitset:test_alloc]")
|
||||||
|
var tab = {}
|
||||||
|
tab[1478] = BitSet.new()
|
||||||
|
assert( tab.size() == 1 )
|
||||||
|
tab[1479] = BitSet.new()
|
||||||
|
assert( tab.size() == 2 )
|
||||||
|
tab.erase(1478)
|
||||||
|
assert( tab.size() == 1 )
|
||||||
|
|
||||||
func test():
|
func test():
|
||||||
print("[bitset] Start check -> start")
|
print("[bitset] Start check -> start")
|
||||||
test_resize()
|
test_resize()
|
||||||
test_put()
|
test_put()
|
||||||
|
test_alloc()
|
||||||
print("[bitset] Start check -> end")
|
print("[bitset] Start check -> end")
|
||||||
|
|
|
@ -148,8 +148,10 @@ func _on_HTTPRequest_request_completed(result, response_code, headers, body):
|
||||||
|
|
||||||
print("[login_menu:_on_HTTPRequest_request_completed] state:" + state + ", cookie:" + cookie + ", fsaddr:" + fsaddr + ", ringmainurl:" + ringmainurl + ", fartp:" + fartp + ", stat:" + stat + ", r2serverversion:" + r2serverversion + ", r2backuppatchurl:" + r2backuppatchurl + ", r2patchurl:" + r2patchurl)
|
print("[login_menu:_on_HTTPRequest_request_completed] state:" + state + ", cookie:" + cookie + ", fsaddr:" + fsaddr + ", ringmainurl:" + ringmainurl + ", fartp:" + fartp + ", stat:" + stat + ", r2serverversion:" + r2serverversion + ", r2backuppatchurl:" + r2backuppatchurl + ", r2patchurl:" + r2patchurl)
|
||||||
var server_info = server_info_script.nel_server_info.new(body.get_string_from_utf8());
|
var server_info = server_info_script.nel_server_info.new(body.get_string_from_utf8());
|
||||||
net_low_level.set_khaganat_server(khaganat_host, khaganat_port)
|
var connexion = load("res://assets/Scripts/Config/connexion.gd").connexion.new()
|
||||||
net_low_level.connect_to_server(UserAddr, UserKey, UserId)
|
var lang = connexion.get_language()
|
||||||
|
print("[login_menu:_on_HTTPRequest_request_completed] khaganat_host:" + khaganat_host + ", khaganat_port:" + str(khaganat_port))
|
||||||
|
net_low_level.connect_to_server(khaganat_host, khaganat_port, UserAddr, UserKey, UserId, lang)
|
||||||
|
|
||||||
emit_signal( "login_button_pressed" )
|
emit_signal( "login_button_pressed" )
|
||||||
|
|
||||||
|
|
7
networkconnexion.gdns
Normal file
7
networkconnexion.gdns
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
[gd_resource type="NativeScript" load_steps=2 format=2]
|
||||||
|
|
||||||
|
[ext_resource path="res://gdnative.gdnlib" type="GDNativeLibrary" id=1]
|
||||||
|
|
||||||
|
[resource]
|
||||||
|
class_name = "NetworkConnection"
|
||||||
|
library = ExtResource( 1 )
|
|
@ -27,6 +27,10 @@ character="*res://game_scene/Game/Character/Character.tscn"
|
||||||
net_low_level="*res://assets/Scripts/Network/net_low_level.gd"
|
net_low_level="*res://assets/Scripts/Network/net_low_level.gd"
|
||||||
msg="*res://assets/Scripts/Definition/msg.gd"
|
msg="*res://assets/Scripts/Definition/msg.gd"
|
||||||
|
|
||||||
|
[debug]
|
||||||
|
|
||||||
|
settings/stdout/verbose_stdout=true
|
||||||
|
|
||||||
[display]
|
[display]
|
||||||
|
|
||||||
window/size/width=1280
|
window/size/width=1280
|
||||||
|
|
Loading…
Reference in a new issue