create module

This commit is contained in:
AleaJactaEst 2020-01-24 19:56:51 +01:00
parent eba1314eb3
commit c6a8820e65
69 changed files with 3485 additions and 407 deletions

View file

@ -15,7 +15,7 @@ func _input(event):
if (event is mouse_event):
is_mouse_event = true
break
# If it is, then pass the event to the viewport
if (is_mouse_event == false):
viewport.input(event)
@ -38,20 +38,20 @@ func _on_area_input_event(camera, event, click_pos, click_normal, shape_idx):
pos.x += event.relative.x / viewport.size.x
pos.y += event.relative.y / viewport.size.y
last_click_pos = pos
# Convert to 2D
pos = Vector2(pos.x, pos.y)
# Convert to viewport coordinate system
# Convert pos to a range from (0 - 1)
pos.y *= -1
pos += Vector2(1, 1)
pos = pos / 2
# Convert pos to be in range of the viewport
pos.x *= viewport.size.x
pos.y *= viewport.size.y
# Set the position in event
event.position = pos
event.global_position = pos
@ -60,7 +60,7 @@ func _on_area_input_event(camera, event, click_pos, click_normal, shape_idx):
if (event is InputEventMouseMotion):
event.relative = pos - prev_pos
prev_pos = pos
# Send the event to the viewport
viewport.input(event)
@ -68,4 +68,3 @@ func _on_area_input_event(camera, event, click_pos, click_normal, shape_idx):
func _ready():
viewport = get_node("Viewport")
get_node("Area").connect("input_event", self, "_on_area_input_event")

View file

@ -2,6 +2,54 @@
Before build and launch client, we need build godot-cpp (lib to connect c++ code to godot engine) and build crypt (c++ module use to authentification with khaganat)
## Build module
```
mkdir build
cd build
# Disable build directory on godot editor
touch .gdignore
# clone godot
git clone https://github.com/godotengine/godot.git
cd godot
# switch on release
git checkout 3.1.2-stable
# Create link with our module (or copy file to godot/modules - as you like)
cd modules
for file in ../../../modules/*
do
if [ -d $file ]
then
echo "$file"
ln -s $file .
fi
done
cd ..
# Copy modules doc to godot
cp modules/*/doc_classes/* doc/classes/.
# Clean project (if you build before)
scons -j$(nproc) -c
# Build
scons -j$(nproc) platform=x11
cd ../..
```
### Generate doc
If you want, you can regenerate doc.
(Normally it's generated)
```
cd build/godot
./bin/godot.x11.tools.64 --doctool .
cp modules/*/doc_classes/* doc/classes/.
```
### Launch godot with module
```
cd build/godot
bin/godot.x11.tools.64
cd ../..
```
## Build godot-cpp
### Initialize

View file

@ -9,4 +9,4 @@ func _enter_tree():
func _exit_tree():
# Clean-up of the plugin goes here
# Always remember to remove it from the engine when deactivated
remove_custom_type("ui_window")
remove_custom_type("ui_window")

View file

@ -71,4 +71,4 @@ class connexion:
self._valid_certificate = value
func set_language(value):
self._language = value
self._language = value

View file

@ -16,8 +16,9 @@ func open_message_xml():
_msg_md5sum = content.md5_text()
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())
#var NetworkConnexion = preload("res://networkconnexion.gdns").new()
var networkconnection = NetworkConnection.new()
networkconnection.define_checksum_msg_xml(content.md5_buffer())
# Load XML data
_msg_xml.open("res://assets/Definition/msg.xml")
@ -63,9 +64,11 @@ func read_all_node():
_msg_data[branch]["leaf"][leaf] = ileaf
ileaf += 1
ret = _msg_xml.read()
var NetworkConnexion = preload("res://networkconnexion.gdns").new()
if ProjectSettings.get_setting("khaganat/debug_mode"):
#print("Branch:" + str(_msg_data.size()))
var sizebranch = _msg_data.size()
#NetworkConnexion.get_master_message_description_node().->set_name("Master")
for key in _msg_data:
var sizeleaf = _msg_data[key]["leaf"].size()
print(" " + key + " -> " + str(_msg_data[key]["pos"]) + "/" + str(sizebranch))
@ -91,4 +94,4 @@ func read_msg(msgin):
func write_msg(value):
pass
pass

View file

@ -15,7 +15,8 @@ class nel_login_message:
self._lg = lg;
func crypt_password(salt):
var crypt = preload("res://crypt.gdns").new()
#var crypt = preload("res://crypt.gdns").new()
var crypt = Crypt.new()
var crypted = crypt.encrypt(self._password, salt)
return crypted

View file

@ -42,4 +42,4 @@ class nel_register:
return "Ryzom"
func get_param_add_user_string():
return "Username=" + self._url_encoding.web_encode(self._username) + "&Password=" + self._url_encoding.web_encode(self._password) + "&ConfirmPass=" + self._url_encoding.web_encode(self._password) + "&Email=" + self._url_encoding.web_encode(self._email) + "&TaC=" + self._url_encoding.web_encode(self._tac) + "&function=add_user"
return "Username=" + self._url_encoding.web_encode(self._username) + "&Password=" + self._url_encoding.web_encode(self._password) + "&ConfirmPass=" + self._url_encoding.web_encode(self._password) + "&Email=" + self._url_encoding.web_encode(self._email) + "&TaC=" + self._url_encoding.web_encode(self._tac) + "&function=add_user"

View file

@ -15,38 +15,34 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# https://godotengine.org/qa/20026/to-send-a-udp-packet-godot-3
extends Control
onready var BitStream = preload("res://bitstream.gdns")
onready var BitSet = preload("res://bitset.gdns")
onready var NetworkConnexion = preload("res://networkconnexion.gdns")
var _networkconnexion
var _networkconnection = NetworkConnection.new()
func _ready():
_networkconnexion = NetworkConnexion.new()
pass
func send_system_login(host, port, user_addr, user_key, user_id, lang):
_networkconnexion.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_quit():
_networkconnexion.send_system_quit()
_networkconnection.send_system_quit()
func send_systemm_disconnect():
_networkconnexion.send_systemm_disconnect()
_networkconnection.send_systemm_disconnect()
func disconnect_server():
_networkconnexion.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)
func _process(delta):
_networkconnexion.process(delta)
_networkconnection.process(delta)
func _exit_tree():
print("[net_low_level] End")
disconnect_server()
disconnect_server()

View file

@ -59,4 +59,4 @@ func ArrayIntToStringHexa(array_int):
var ret = ""
for data in array_int:
ret += IntToStringHexa(data)
return ret
return ret

View file

@ -16,5 +16,4 @@ fog_depth_enabled = false
tonemap_mode = 2
ss_reflections_enabled = true
ssao_enabled = true
ssao_quality = 1
glow_bloom = 0.2

View file

@ -1,7 +1,6 @@
[gd_scene load_steps=10 format=2]
[sub_resource type="Shader" id=1]
code = "shader_type spatial;
render_mode blend_mix,depth_draw_opaque,cull_back,diffuse_burley,specular_schlick_ggx;
uniform vec4 albedo : hint_color;
@ -40,8 +39,6 @@ void fragment() {
"
[sub_resource type="ShaderMaterial" id=2]
render_priority = 0
shader = SubResource( 1 )
shader_param/albedo = Color( 1, 1, 1, 1 )
shader_param/specular = 0.5
@ -54,10 +51,8 @@ shader_param/uv1_scale = Vector3( 1, 1, 1 )
shader_param/uv1_offset = Vector3( 0, 0, 0 )
shader_param/uv2_scale = Vector3( 1, 1, 1 )
shader_param/uv2_offset = Vector3( 0, 0, 0 )
_sections_unfolded = [ "shader_param" ]
[sub_resource type="Shader" id=3]
code = "shader_type spatial;
render_mode blend_mix,depth_draw_opaque,cull_back,diffuse_burley,specular_schlick_ggx;
uniform vec4 albedo : hint_color;
@ -96,8 +91,6 @@ void fragment() {
"
[sub_resource type="ShaderMaterial" id=4]
render_priority = 0
shader = SubResource( 3 )
shader_param/albedo = Color( 0.328125, 0.203706, 0.103821, 1 )
shader_param/specular = 0.0
@ -110,10 +103,8 @@ shader_param/uv1_scale = Vector3( 1, 1, 1 )
shader_param/uv1_offset = Vector3( 0, 0, 0 )
shader_param/uv2_scale = Vector3( 1, 1, 1 )
shader_param/uv2_offset = Vector3( 0, 0, 0 )
_sections_unfolded = [ "shader_param" ]
[sub_resource type="Shader" id=5]
code = "shader_type spatial;
render_mode blend_mix,depth_draw_opaque,cull_back,diffuse_burley,specular_schlick_ggx;
uniform vec4 albedo : hint_color;
@ -152,8 +143,6 @@ void fragment() {
"
[sub_resource type="ShaderMaterial" id=6]
render_priority = 0
shader = SubResource( 5 )
shader_param/albedo = Color( 0, 0, 0, 1 )
shader_param/specular = 0.5
@ -166,10 +155,8 @@ shader_param/uv1_scale = Vector3( 1, 1, 1 )
shader_param/uv1_offset = Vector3( 0, 0, 0 )
shader_param/uv2_scale = Vector3( 1, 1, 1 )
shader_param/uv2_offset = Vector3( 0, 0, 0 )
_sections_unfolded = [ "shader_param" ]
[sub_resource type="Shader" id=7]
code = "shader_type spatial;
render_mode blend_mix,depth_draw_opaque,cull_back,diffuse_burley,specular_schlick_ggx;
uniform vec4 albedo : hint_color;
@ -208,8 +195,6 @@ void fragment() {
"
[sub_resource type="ShaderMaterial" id=8]
render_priority = 0
shader = SubResource( 7 )
shader_param/albedo = Color( 0.231426, 0.484375, 0.223267, 1 )
shader_param/specular = 0.5
@ -222,12 +207,9 @@ shader_param/uv1_scale = Vector3( 1, 1, 1 )
shader_param/uv1_offset = Vector3( 0, 0, 0 )
shader_param/uv2_scale = Vector3( 1, 1, 1 )
shader_param/uv2_offset = Vector3( 0, 0, 0 )
_sections_unfolded = [ "shader_param" ]
[sub_resource type="ArrayMesh" id=9]
blend_shape_mode = 0
custom_aabb = AABB( 0, 0, 0, 0, 0, 0 )
blend_shape/names = PoolStringArray( "big_ears", "small_ears" )
blend_shape/mode = 0
surfaces/0 = {
@ -282,30 +264,15 @@ surfaces/3 = {
"skeleton_aabb": [ ],
"vertex_count": 48
}
_sections_unfolded = [ "blend_shape", "surface_1", "surface_2", "surface_3", "surface_4" ]
[node name="suzanne" type="Spatial"]
[node name="mesh" type="MeshInstance" parent="." index="0"]
[node name="mesh" type="MeshInstance" parent="."]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0.0146484, 0, 0 )
layers = 1
material_override = null
cast_shadow = 1
extra_cull_margin = 0.0
use_in_baked_light = false
lod_min_distance = 0.0
lod_min_hysteresis = 0.0
lod_max_distance = 0.0
lod_max_hysteresis = 0.0
mesh = SubResource( 9 )
skeleton = NodePath("..")
blend_shapes/big_ears = 0.0
blend_shapes/small_ears = 0.0
material/0 = null
material/1 = null
material/2 = null
material/3 = null
_sections_unfolded = [ "blend_shapes", "material" ]

View file

@ -55,7 +55,8 @@ BitSet::BitSet()
BitSet::~BitSet()
{
// add your cleanup here
delete [] this->_data;
if ( this->_data != nullptr )
delete [] this->_data;
}
void BitSet::_init()
@ -100,6 +101,8 @@ void BitSet::clear_data()
void BitSet::set_bit(uint32_t bit_number)
{
if (bit_number >= this->_size_byte)
throw "Out of range";
uint32_t mask = bit_number & (BITSET_SIZE - 1);
mask = 1 << mask;
this->_data[bit_number>>5] |= mask;
@ -107,6 +110,8 @@ void BitSet::set_bit(uint32_t bit_number)
void BitSet::clear_bit(uint32_t bit_number)
{
if (bit_number >= this->_size_byte)
throw "Out of range";
uint32_t mask = bit_number & (BITSET_SIZE - 1);
mask = 1 << mask;
this->_data[bit_number>>5] &= mask;
@ -114,6 +119,8 @@ void BitSet::clear_bit(uint32_t bit_number)
void BitSet::put(uint32_t bit_number, bool value)
{
if (bit_number >= this->_size_byte)
throw "Out of range";
if ( value )
this->set_bit(bit_number);
else
@ -122,6 +129,8 @@ void BitSet::put(uint32_t bit_number, bool value)
bool BitSet::get(uint32_t bit_number)
{
if (bit_number >= this->_size_byte)
throw "Out of range";
uint32_t mask = bit_number & (BITSET_SIZE - 1);
mask = 1 << mask;
return this->_data[bit_number>>5] & mask != 0;
@ -152,4 +161,4 @@ String BitSet::show()
BitStream msgout;
this->write_serial(&msgout);
return msgout.show();
}
}

View file

@ -26,7 +26,7 @@
namespace godot {
class BitSet : public Reference {
class BitSet : public Reference {
GODOT_CLASS(BitSet, Reference)
private:
uint32_t _num_bits;

View file

@ -22,6 +22,7 @@
#include "bitset.h"
#include "crypt.h"
#include "network_connection.h"
#include "message_description_node.h"
/** GDNative Initialize **/
extern "C" void GDN_EXPORT godot_gdnative_init(godot_gdnative_init_options *o) {
@ -42,4 +43,5 @@ extern "C" void GDN_EXPORT godot_nativescript_init(void *handle) {
godot::register_class<godot::BitSet>();
godot::register_class<godot::Crypt>();
godot::register_class<godot::NetworkConnection>();
godot::register_class<godot::MessageDescriptionNode>();
}

View file

@ -38,6 +38,7 @@ void NetworkConnection::_register_methods()
register_method("disconnect_server", &NetworkConnection::disconnect_server);
register_method("process", &NetworkConnection::process);
register_method("get_state", &NetworkConnection::get_state);
register_method("get_master_message_description_node", &NetworkConnection::get_master_message_description_node);
}
NetworkConnection::NetworkConnection()
@ -87,6 +88,11 @@ void NetworkConnection::process(int delta)
NetworkConnectionCore::get_singleton()->process(delta);
}
MessageDescriptionNode & NetworkConnection::get_master_message_description_node()
{
return NetworkConnectionCore::get_singleton()->get_master_message_description_node();
}
void terminate_network_connection()
{
NetworkConnectionCore::get_singleton()->terminate_connexion();

View file

@ -52,6 +52,8 @@ public:
void disconnect_server();
void process(int delta);
int get_state();
MessageDescriptionNode & get_master_message_description_node();
};
}

View file

@ -480,3 +480,8 @@ void NetworkConnectionCore::terminate_connexion()
delete this-> _socketUDP;
this->_socketUDP = NULL;
}
MessageDescriptionNode & NetworkConnectionCore::get_master_message_description_node()
{
return this->_message_description_node;
}

View file

@ -28,6 +28,7 @@
#include "clfecommon.h"
#include "store_message.h"
#include "state.h"
#include "message_description_node.h"
#define MAX_LOOP_READ_BY_STEP 10
#define NUM_BITS_IN_LONG_ACK 512
@ -52,6 +53,7 @@ private:
int32_t _last_ack_bit;
int32_t _last_ack_in_long_ack;
StoreMessage queue;
MessageDescriptionNode _message_description_node;
public:
static NetworkConnectionCore * get_singleton();
@ -81,6 +83,7 @@ public:
void process(int delta);
bool connected();
void terminate_connexion();
MessageDescriptionNode & get_master_message_description_node();
};
}

View file

@ -13,28 +13,30 @@ func _ready():
# pass
func test_resize():
var bitset = preload("res://bitset.gdns").new()
#var bitset = preload("res://bitset.gdns").new()
var bitset = BitSet.new()
print ("[bitset:test_resize]")
bitset.resize(1024)
func test_put():
var bitset = preload("res://bitset.gdns").new()
print ("[bitset:test_init]")
#var bitset = preload("res://bitset.gdns").new()
var bitset = BitSet.new()
print ("[bitset:test_put]")
bitset.resize(1024)
#print ("[bitset:test_init] " + bitset.show())
#print ("[bitset:test_put] " + bitset.show())
assert( bitset.show() == "0000000000000000000000000000010000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
bitset.put(1, 1)
#print ("[bitset:test_init] " + bitset.show())
#print ("[bitset:test_put] " + bitset.show())
assert( bitset.show() == "0000000000000000000000000000010000000000000000000000000000000000001000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
bitset.put(2, 1)
#print ("[bitset:test_init] " + bitset.show())
#print ("[bitset:test_put] " + bitset.show())
assert( bitset.show() == "0000000000000000000000000000010000000000000000000000000000000000001000000000000000000000000000000000011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
bitset.put(1, 0)
#print ("[bitset:test_init] " + bitset.show())
#print ("[bitset:test_put] " + bitset.show())
assert( bitset.show() == "0000000000000000000000000000010000000000000000000000000000000000001000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
func test_alloc():
var BitSet = preload("res://bitset.gdns")
#var BitSet = preload("res://bitset.gdns")
print ("[bitset:test_alloc]")
var tab = {}
tab[1478] = BitSet.new()

View file

@ -13,19 +13,22 @@ func _ready():
# pass
func test_bool_true():
var bitstream = preload("res://bitstream.gdns").new()
#var bitstream = preload("res://bitstream.gdns").new()
var bitstream = BitStream.new()
bitstream.put_bool(true)
var res = bitstream.show()
assert(res == "1")
func test_bool_false():
var bitstream = preload("res://bitstream.gdns").new()
#var bitstream = preload("res://bitstream.gdns").new()
var bitstream = BitStream.new()
bitstream.put_bool(false)
var res = bitstream.show()
assert(res == "0")
func test_uint8():
var bitstream = preload("res://bitstream.gdns").new()
#var bitstream = preload("res://bitstream.gdns").new()
var bitstream = BitStream.new()
var res
bitstream.put_uint8(18)
res = bitstream.show()
@ -41,13 +44,14 @@ func test_uint8():
#print(res)
assert(res == "000100101111111111100010")
# Ignore String (replaced by 'A' -> 0)
bitstream.put_uint8("A")
bitstream.put_char("A")
res = bitstream.show()
#print(res)
assert(res == "00010010111111111110001000000000")
assert(res == "00010010111111111110001001000001")
func test_sint8():
var bitstream = preload("res://bitstream.gdns").new()
#var bitstream = preload("res://bitstream.gdns").new()
var bitstream = BitStream.new()
var res
bitstream.put_sint8(-18)
res = bitstream.show()
@ -63,13 +67,14 @@ func test_sint8():
#print(res)
assert(res == "111011101111111100011110")
# Ignore String (replaced by 'A' -> 0)
bitstream.put_sint8("A")
bitstream.put_char("A")
res = bitstream.show()
#print(res)
assert(res == "11101110111111110001111000000000")
assert(res == "11101110111111110001111001000001")
func test_uint16():
var bitstream = preload("res://bitstream.gdns").new()
#var bitstream = preload("res://bitstream.gdns").new()
var bitstream = BitStream.new()
var res
bitstream.put_uint16(18)
res = bitstream.show()
@ -84,14 +89,10 @@ func test_uint16():
res = bitstream.show()
#print(res)
assert(res == "000000000001001011111111111111110011100100000101")
# Ignore String (replaced by 'A' -> 0)
bitstream.put_uint16("A")
res = bitstream.show()
#print(res)
assert(res == "0000000000010010111111111111111100111001000001010000000000000000")
func test_sint16():
var bitstream = preload("res://bitstream.gdns").new()
#var bitstream = preload("res://bitstream.gdns").new()
var bitstream = BitStream.new()
var res
bitstream.put_sint16(-18)
res = bitstream.show()
@ -106,14 +107,10 @@ func test_sint16():
res = bitstream.show()
#print(res)
assert(res == "111111111110111011111111111111111111101100011110")
# Ignore String (replaced by 'A' -> 0)
bitstream.put_sint16("A")
res = bitstream.show()
#print(res)
assert(res == "1111111111101110111111111111111111111011000111100000000000000000")
func test_uint32():
var bitstream = preload("res://bitstream.gdns").new()
#var bitstream = preload("res://bitstream.gdns").new()
var bitstream = BitStream.new()
var res
bitstream.put_uint32(1459747891)
res = bitstream.show()
@ -128,14 +125,10 @@ func test_uint32():
res = bitstream.show()
#print(res)
assert(res == "010101110000000111111100001100111111111111111111111111111111111100000000000000000011100100000101")
# Ignore String (replaced by 'A' -> 0)
bitstream.put_uint32("A")
res = bitstream.show()
#print(res)
assert(res == "01010111000000011111110000110011111111111111111111111111111111110000000000000000001110010000010100000000000000000000000000000000")
func test_sint32():
var bitstream = preload("res://bitstream.gdns").new()
#var bitstream = preload("res://bitstream.gdns").new()
var bitstream = BitStream.new()
var res
bitstream.put_sint32(-18)
res = bitstream.show()
@ -150,33 +143,26 @@ func test_sint32():
res = bitstream.show()
#print(res)
assert(res == "111111111111111111111111111011101111111111111111111111111111111111111111111111111111101100011110")
# Ignore String (replaced by 'A' -> 0)
bitstream.put_sint32("A")
res = bitstream.show()
#print(res)
assert(res == "11111111111111111111111111101110111111111111111111111111111111111111111111111111111110110001111000000000000000000000000000000000")
func test_string_hexa32():
var bitstream = preload("res://bitstream.gdns").new()
#var bitstream = preload("res://bitstream.gdns").new()
var bitstream = BitStream.new()
var res
bitstream.put_string_hexa32(1)
res = bitstream.show()
#print(res)
assert(res == "00000000000000000000000000000001")
bitstream.put_string_hexa32("DEADBEAF")
res = bitstream.show()
#print(res)
assert(res == "0000000000000000000000000000000111011110101011011011111010101111")
bitstream = preload("res://bitstream.gdns").new()
assert(res == "11011110101011011011111010101111")
bitstream = BitStream.new()
bitstream.put_string_hexa32("010011AC")
res = bitstream.show()
#print(res)
assert(res == "00000001000000000001000110101100")
func test_char():
var bitstream = preload("res://bitstream.gdns").new()
#var bitstream = preload("res://bitstream.gdns").new()
var bitstream = BitStream.new()
var res
bitstream.put_char(1)
bitstream.put_char("1")
res = bitstream.show()
#print(res)
assert(res == "00110001")
@ -186,19 +172,16 @@ func test_char():
assert(res == "0011000101000001")
func test_string():
var bitstream = preload("res://bitstream.gdns").new()
#var bitstream = preload("res://bitstream.gdns").new()
var bitstream = BitStream.new()
var res
bitstream.put_string(1)
res = bitstream.show()
#print(res)
assert(res == "0000000000000000000000000000000100110001")
bitstream.put_string("FR")
res = bitstream.show()
#print(res)
assert(res == "0000000000000000000000000000000100110001000000000000000000000000000000100100011001010010")
assert(res == "000000000000000000000000000000100100011001010010")
func test_little_endian():
var bitstream = preload("res://bitstream.gdns").new()
#var bitstream = preload("res://bitstream.gdns").new()
var bitstream = BitStream.new()
var res = bitstream.is_little_endian()
print ("[bitstream] little endian : " + str(res))

View file

@ -0,0 +1,84 @@
extends Node
# Declare member variables here. Examples:
# var a = 2
# var b = "text"
# Called when the node enters the scene tree for the first time.
func _ready():
pass # Replace with function body.
func test_init():
#var bitstream = preload("res://bitstream.gdns").new()
var bitstreamqueue = BitStreamQueue.new()
var res = bitstreamqueue.length()
assert(res == 0)
bitstreamqueue.clear()
res = bitstreamqueue.get_received_number(0)
assert(res == 0)
func test_msg_1():
var bitstreamqueue = BitStreamQueue.new()
var pos
var res
var tmp = PoolByteArray()
tmp.append(0)
tmp.append(0)
tmp.append(0)
tmp.append(3)
tmp.append(2)
res = bitstreamqueue.length()
assert(res == 0)
pos = bitstreamqueue.put_msgbytes(tmp)
res = bitstreamqueue.get_received_number(pos)
assert(res == 3)
res = bitstreamqueue.get_msg(pos)
#print(res.show())
assert(res.show() == "0000000000000000000000000000001100000010")
res = bitstreamqueue.get_received_number(pos)
assert(res == 3)
res = bitstreamqueue.length()
assert(res == 1)
bitstreamqueue.erase(pos)
res = bitstreamqueue.length()
assert(res == 0)
func test_msg_2():
var bitstreamqueue = BitStreamQueue.new()
var pos
var res
var tmp = PoolByteArray()
tmp.append(0)
tmp.append(0)
tmp.append(0)
tmp.append(2)
tmp.append(7)
pos = bitstreamqueue.put_msgbytes(tmp)
res = bitstreamqueue.get_received_number(pos)
assert(res == 2)
res = bitstreamqueue.get_msg(pos)
#print(res.show())
assert(res.show() == "0000000000000000000000000000001000000111")
res = bitstreamqueue.get_received_number(pos)
assert(res == 2)
func test():
print("[bitstreamqueue] Start check -> start")
test_init()
test_msg_1()
test_msg_2()
print("[bitstreamqueue] Start check -> end")

View file

@ -10,7 +10,8 @@ func _ready():
func test():
print("[crypt] Start check -> start")
var crypt = load("res://crypt.gdns").new()
#var crypt = load("res://crypt.gdns").new()
var crypt = Crypt.new()
var salt = "$6$mZ3k4xrnvjLM8dV6"
var password = "tester"
var crypted = crypt.encrypt(password, salt)

View file

@ -36,6 +36,8 @@ func launch_gdscript_test():
bitstream.test()
var bitset = preload("res://gdnative/test/bitset.gd").new()
bitset.test()
var bitstreamqueue = preload("res://gdnative/test/bitstreamqueue.gd").new()
bitstreamqueue.test()
print("[global] Launch test gdscript -> End")
return true

View file

@ -123,4 +123,4 @@ func _on_CancelButton_pressed():
func _unhandled_input(event):
if event is InputEventKey:
if event.pressed and event.scancode == KEY_ESCAPE:
emit_signal( "return_pressed" )
emit_signal( "return_pressed" )

View file

@ -23,7 +23,7 @@ var syllabes_tcara_trad = [ "TradTmachin", "TradTtruc", "TradTbidule", "TradTcho
var character_preview
func _ready():
var popup_node = $margin_container/v_box_container/generate_name_box/region_menu
var popup = popup_node.get_popup()
popup.add_item( "Khanat" )
@ -33,7 +33,7 @@ func _ready():
self.character_preview = self.get_node( "../../../viewport/character" )
func _on_return_button_pressed():
emit_signal( "return_button_pressed" )
@ -44,7 +44,7 @@ func _on_valid_button_pressed():
func show_error( string ):
$margin_container/v_box_container/error_label.set( "custom_colors/font_color", Color( 1, 0, 0, 1 ))
$margin_container/v_box_container/error_label.text = string
func show_help( string ):
$margin_container/v_box_container/error_label.set( "custom_colors/font_color", Color( 0, 1, 0, 1 ))
$margin_container/v_box_container/error_label.text = string
@ -86,14 +86,14 @@ func _on_generate_name_pressed():
if nom_index+1 < nb_noms:
name += " "
trad += " / "
$margin_container/v_box_container/name_box/line_edit.text = name
self.show_help( trad )
func _on_sex_bar_value_changed( value ):
emit_signal( "sex_bar_changed", value )
func _on_size_bar_value_changed( value ):
emit_signal( "size_bar_changed", value )
@ -102,5 +102,5 @@ func _on_ears_size_value_changed(value):
func _on_eyes_color_color_changed(color):
emit_signal( "eyes_color_changed", color )

View file

@ -16,188 +16,72 @@
[ext_resource path="res://assets/GUI/images/button_light_on.png" type="Texture" id=14]
[sub_resource type="ViewportTexture" id=1]
resource_local_to_scene = true
flags = 0
viewport_path = NodePath("viewport")
[node name="character_selection_menu" type="Control" index="0"]
anchor_left = 0.0
anchor_top = 0.0
[node name="character_selection_menu" type="Control"]
anchor_right = 1.0
anchor_bottom = 1.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
theme = ExtResource( 1 )
script = ExtResource( 2 )
_sections_unfolded = [ "Theme" ]
[node name="viewport" type="Viewport" parent="." index="0"]
arvr = false
[node name="viewport" type="Viewport" parent="."]
size = Vector2( 1024, 1024 )
own_world = false
world = null
transparent_bg = true
msaa = 2
hdr = true
disable_3d = false
usage = 2
debug_draw = 0
render_target_v_flip = true
render_target_clear_mode = 0
render_target_update_mode = 2
audio_listener_enable_2d = false
audio_listener_enable_3d = false
physics_object_picking = false
gui_disable_input = false
gui_snap_controls_to_pixels = true
shadow_atlas_size = 0
shadow_atlas_quad_0 = 2
shadow_atlas_quad_1 = 2
shadow_atlas_quad_2 = 3
shadow_atlas_quad_3 = 4
_sections_unfolded = [ "Render Target", "Rendering" ]
[node name="character" parent="viewport" index="0" instance=ExtResource( 3 )]
[node name="character" parent="viewport" instance=ExtResource( 3 )]
transform = Transform( 0.371345, 0, 0, 0, 0.218854, 0, 0, 0, 0.371345, 0.000610344, -0.00217155, 6.02408 )
[node name="face_camera" type="Camera" parent="viewport/character" index="4"]
transform = Transform( -1, 0, -8.74228e-008, 0, 1, 0, 8.74228e-008, 0, -1, 0, 1.94589, -2.44418 )
keep_aspect = 1
cull_mask = 1048575
environment = null
h_offset = 0.0
v_offset = 0.0
doppler_tracking = 0
[node name="face_camera" type="Camera" parent="viewport/character"]
transform = Transform( -1, 0, -8.74228e-08, 0, 1, 0, 8.74228e-08, 0, -1, 0, 1.94589, -2.44418 )
projection = 1
current = false
fov = 70.0
size = 2.0
near = 0.05
far = 100.0
_sections_unfolded = [ "Transform" ]
[node name="face_lights" type="Spatial" parent="viewport/character" index="5"]
[node name="face_lights" type="Spatial" parent="viewport/character"]
editor/display_folded = true
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1.27005, 0 )
[node name="face_light_right" type="OmniLight" parent="viewport/character/face_lights" index="0"]
[node name="face_light_right" type="OmniLight" parent="viewport/character/face_lights"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0.377365, 3.59212, -0.568276 )
layers = 1
light_color = Color( 0.742188, 0.945618, 1, 1 )
light_energy = 0.5
light_indirect_energy = 1.0
light_negative = false
light_specular = 0.5
light_bake_mode = 1
light_cull_mask = -1
shadow_enabled = false
shadow_color = Color( 0, 0, 0, 1 )
shadow_bias = 0.15
shadow_contact = 0.0
shadow_reverse_cull_face = false
editor_only = false
omni_range = 5.0
omni_attenuation = 1.0
omni_shadow_mode = 1
omni_shadow_detail = 1
_sections_unfolded = [ "Light" ]
[node name="face_light_left" type="OmniLight" parent="viewport/character/face_lights" index="1"]
[node name="face_light_left" type="OmniLight" parent="viewport/character/face_lights"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -0.385559, 3.59212, -0.568276 )
layers = 1
light_color = Color( 0.741176, 0.945098, 1, 1 )
light_energy = 0.5
light_indirect_energy = 1.0
light_negative = false
light_specular = 0.5
light_bake_mode = 1
light_cull_mask = -1
shadow_enabled = false
shadow_color = Color( 0, 0, 0, 1 )
shadow_bias = 0.15
shadow_contact = 0.0
shadow_reverse_cull_face = false
editor_only = false
omni_range = 5.0
omni_attenuation = 1.0
omni_shadow_mode = 1
omni_shadow_detail = 1
_sections_unfolded = [ "Light" ]
[node name="texture_rect" type="TextureRect" parent="." index="1"]
anchor_left = 0.0
anchor_top = 0.0
[node name="texture_rect" type="TextureRect" parent="."]
anchor_right = 1.0
anchor_bottom = 1.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 1
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
texture = ExtResource( 4 )
expand = true
stretch_mode = 7
_sections_unfolded = [ "Size Flags" ]
[node name="margin_container" type="MarginContainer" parent="." index="2"]
anchor_left = 0.0
anchor_top = 0.0
[node name="margin_container" type="MarginContainer" parent="."]
anchor_right = 1.0
anchor_bottom = 1.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 1
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
custom_constants/margin_right = 8
custom_constants/margin_top = 8
custom_constants/margin_left = 8
custom_constants/margin_bottom = 8
_sections_unfolded = [ "Mouse", "Size Flags", "custom_constants" ]
[node name="character_box" type="HBoxContainer" parent="margin_container" index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
[node name="character_box" type="HBoxContainer" parent="margin_container"]
margin_left = 8.0
margin_top = 8.0
margin_right = 1272.0
margin_bottom = 712.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 1
mouse_default_cursor_shape = 0
size_flags_horizontal = 3
size_flags_vertical = 3
alignment = 0
_sections_unfolded = [ "Mouse", "Size Flags", "custom_constants" ]
[node name="character_slots" parent="margin_container/character_box" index="0" instance=ExtResource( 5 )]
[node name="character_slots" parent="margin_container/character_box" instance=ExtResource( 5 )]
margin_top = 335.0
margin_right = 64.0
margin_bottom = 368.0
[node name="character_creation_box" parent="margin_container/character_box" index="1" instance=ExtResource( 6 )]
[node name="character_creation_box" parent="margin_container/character_box" instance=ExtResource( 6 )]
visible = false
margin_left = 196.0
margin_top = 0.0
@ -206,223 +90,88 @@ margin_bottom = 704.0
size_flags_horizontal = 7
size_flags_vertical = 7
[node name="v_box_container" type="VBoxContainer" parent="margin_container/character_box" index="2"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
[node name="v_box_container" type="VBoxContainer" parent="margin_container/character_box"]
margin_left = 634.0
margin_right = 1264.0
margin_bottom = 704.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 1
mouse_default_cursor_shape = 0
size_flags_horizontal = 3
size_flags_vertical = 3
alignment = 0
_sections_unfolded = [ "Mouse", "Size Flags" ]
[node name="character_preview_image" type="TextureRect" parent="margin_container/character_box/v_box_container" index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
[node name="character_preview_image" type="TextureRect" parent="margin_container/character_box/v_box_container"]
margin_right = 630.0
margin_bottom = 668.0
rect_min_size = Vector2( 512, 512 )
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 1
mouse_default_cursor_shape = 0
size_flags_horizontal = 7
size_flags_vertical = 7
texture = SubResource( 1 )
expand = true
stretch_mode = 6
_sections_unfolded = [ "Axis Stretch", "Grow Direction", "Margin", "Mouse", "Rect", "Size Flags" ]
[node name="h_box_container" type="HBoxContainer" parent="margin_container/character_box/v_box_container" index="1"]
[node name="h_box_container" type="HBoxContainer" parent="margin_container/character_box/v_box_container"]
editor/display_folded = true
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_left = 227.0
margin_top = 672.0
margin_right = 403.0
margin_bottom = 704.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 1
mouse_default_cursor_shape = 2
size_flags_horizontal = 6
size_flags_vertical = 0
alignment = 0
_sections_unfolded = [ "Mouse", "Size Flags" ]
[node name="turn_left" type="TextureButton" parent="margin_container/character_box/v_box_container/h_box_container" index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
[node name="turn_left" type="TextureButton" parent="margin_container/character_box/v_box_container/h_box_container"]
margin_right = 32.0
margin_bottom = 32.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
hint_tooltip = "Tourner le modele vers la gauche."
focus_mode = 2
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
toggle_mode = false
action_mode = 0
enabled_focus_mode = 2
shortcut = null
group = null
texture_normal = ExtResource( 7 )
texture_pressed = ExtResource( 8 )
_sections_unfolded = [ "Hint", "Rect", "Textures" ]
[node name="zoom_out" type="TextureButton" parent="margin_container/character_box/v_box_container/h_box_container" index="1"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
[node name="zoom_out" type="TextureButton" parent="margin_container/character_box/v_box_container/h_box_container"]
margin_left = 36.0
margin_right = 68.0
margin_bottom = 32.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
hint_tooltip = "Zoom arrière."
focus_mode = 2
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
toggle_mode = false
enabled_focus_mode = 2
shortcut = null
group = null
texture_normal = ExtResource( 9 )
_sections_unfolded = [ "Hint", "Textures" ]
[node name="zoom_in" type="TextureButton" parent="margin_container/character_box/v_box_container/h_box_container" index="2"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
[node name="zoom_in" type="TextureButton" parent="margin_container/character_box/v_box_container/h_box_container"]
margin_left = 72.0
margin_right = 104.0
margin_bottom = 32.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
hint_tooltip = "Zoom avant."
focus_mode = 2
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
toggle_mode = false
enabled_focus_mode = 2
shortcut = null
group = null
texture_normal = ExtResource( 10 )
_sections_unfolded = [ "Hint", "Textures" ]
[node name="turn_right" type="TextureButton" parent="margin_container/character_box/v_box_container/h_box_container" index="3"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
[node name="turn_right" type="TextureButton" parent="margin_container/character_box/v_box_container/h_box_container"]
margin_left = 108.0
margin_right = 140.0
margin_bottom = 32.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
hint_tooltip = "Tourner le modele vers la droite."
focus_mode = 2
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
toggle_mode = false
action_mode = 0
enabled_focus_mode = 2
shortcut = null
group = null
texture_normal = ExtResource( 11 )
texture_pressed = ExtResource( 12 )
_sections_unfolded = [ "Hint", "Textures" ]
[node name="lights" type="TextureButton" parent="margin_container/character_box/v_box_container/h_box_container" index="4"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
[node name="lights" type="TextureButton" parent="margin_container/character_box/v_box_container/h_box_container"]
margin_left = 144.0
margin_right = 176.0
margin_bottom = 32.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
hint_tooltip = "Lumières ON/OFF"
focus_mode = 2
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
toggle_mode = true
pressed = true
enabled_focus_mode = 2
shortcut = null
group = null
texture_normal = ExtResource( 13 )
texture_pressed = ExtResource( 14 )
_sections_unfolded = [ "Hint", "Textures" ]
[connection signal="return_button_pressed" from="margin_container/character_box/character_slots" to="." method="_on_character_slots_return_button_pressed"]
[connection signal="character_preview_need_update" from="margin_container/character_box/character_creation_box" to="." method="_on_character_creation_box_character_preview_need_update"]
[connection signal="creation_button_pressed" from="margin_container/character_box/character_creation_box" to="." method="_on_character_creation_box_creation_button_pressed"]
[connection signal="ears_size_bar_changed" from="margin_container/character_box/character_creation_box" to="." method="_on_character_creation_box_ears_size_bar_changed"]
[connection signal="eyes_color_changed" from="margin_container/character_box/character_creation_box" to="." method="_on_character_creation_box_eyes_color_changed"]
[connection signal="return_button_pressed" from="margin_container/character_box/character_creation_box" to="." method="_on_character_creation_box_return_button_pressed"]
[connection signal="sex_bar_changed" from="margin_container/character_box/character_creation_box" to="." method="_on_character_creation_box_sex_bar_changed"]
[connection signal="size_bar_changed" from="margin_container/character_box/character_creation_box" to="." method="_on_character_creation_box_size_bar_changed"]
[connection signal="resized" from="margin_container/character_box/v_box_container/character_preview_image" to="." method="_on_character_preview_image_resized"]
[connection signal="button_down" from="margin_container/character_box/v_box_container/h_box_container/turn_left" to="." method="_on_turn_left_button_down"]
[connection signal="button_up" from="margin_container/character_box/v_box_container/h_box_container/turn_left" to="." method="_on_turn_left_button_up"]
[connection signal="button_down" from="margin_container/character_box/v_box_container/h_box_container/zoom_out" to="." method="_on_zoom_out_button_down"]
[connection signal="button_up" from="margin_container/character_box/v_box_container/h_box_container/zoom_out" to="." method="_on_zoom_out_button_up"]
[connection signal="button_down" from="margin_container/character_box/v_box_container/h_box_container/zoom_in" to="." method="_on_zoom_in_button_down"]
[connection signal="button_up" from="margin_container/character_box/v_box_container/h_box_container/zoom_in" to="." method="_on_zoom_in_button_up"]
[connection signal="button_down" from="margin_container/character_box/v_box_container/h_box_container/turn_right" to="." method="_on_turn_right_button_down"]
[connection signal="button_up" from="margin_container/character_box/v_box_container/h_box_container/turn_right" to="." method="_on_turn_right_button_up"]
[connection signal="toggled" from="margin_container/character_box/v_box_container/h_box_container/lights" to="." method="_on_lights_toggled"]

View file

@ -72,8 +72,6 @@ margin_bottom = 61.0
texture_normal = ExtResource( 12 )
[connection signal="character_selected" from="character_selection_menu" to="." method="_on_character_selection_menu_character_selected"]
[connection signal="return_button_pressed" from="character_selection_menu" to="." method="_on_character_selection_menu_return_button_pressed"]
[connection signal="login_button_pressed" from="login_menu" to="." method="_on_login_menu_login_button_pressed"]
[connection signal="register_button_pressed" from="login_menu" to="." method="_on_login_menu_register_button_pressed"]
[connection signal="cancel_button_pressed" from="register_menu" to="." method="_on_register_menu_cancel_button_pressed"]
[connection signal="license_button_pressed" from="register_menu" to="." method="_on_register_menu_license_button_pressed"]
[connection signal="register_account_created" from="register_menu" to="." method="_on_register_menu_register_account_created"]

0
modules/.gdignore Normal file
View file

2
modules/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
__pycache__/
*.o

5
modules/bitset/SCsub Normal file
View file

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

186
modules/bitset/bitset.cpp Normal file
View file

@ -0,0 +1,186 @@
/*
* Class BitSet
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/>.
Build :
scons platform=linux bits=64
*/
// #include <iostream>
#include "bitset.h"
#define BITSET_SIZE 32
void BitSet::_bind_methods()
{
ClassDB::bind_method(D_METHOD("size"), &BitSet::size);
ClassDB::bind_method(D_METHOD("resize", "num_bits"), &BitSet::resize);
ClassDB::bind_method(D_METHOD("clear"), &BitSet::clear);
ClassDB::bind_method(D_METHOD("clear_data"), &BitSet::clear_data);
ClassDB::bind_method(D_METHOD("set_bit", "bit_number"), &BitSet::set_bit);
ClassDB::bind_method(D_METHOD("clear_bit", "bit_number"), &BitSet::clear_bit);
ClassDB::bind_method(D_METHOD("put", "bit_number", "value"), &BitSet::put);
ClassDB::bind_method(D_METHOD("get", "bit_number"), &BitSet::get);
ClassDB::bind_method(D_METHOD("write_serial", "msgout"), &BitSet::write_serial);
ClassDB::bind_method(D_METHOD("read_serial", "msgin"), &BitSet::read_serial);
ClassDB::bind_method(D_METHOD("show"), &BitSet::show);
}
BitSet::BitSet()
{
this->_num_bits = 8;
this->_size_byte = 1;
this->_mask_last = 0;
this->_data = new uint32_t[1];
}
BitSet::~BitSet()
{
// add your cleanup here
if ( this->_data != nullptr )
delete [] this->_data;
}
int BitSet::size()
{
return this->_size_byte;
}
void BitSet::resize(uint32_t num_bits)
{
uint32_t n_last_bits;
uint32_t new_size_byte = (num_bits + BITSET_SIZE - 1) / BITSET_SIZE;
new_size_byte = (num_bits + BITSET_SIZE - 1) / BITSET_SIZE;
if (this->_size_byte != new_size_byte )
{
this->_size_byte = new_size_byte;
delete [] this->_data;
this->_data = new uint32_t[this->_size_byte];
if ( this->_data == nullptr )
{
ERR_PRINT("[BitSet::set_bit] Allocation error");
throw "Allocation error";
}
}
this->_num_bits = num_bits;
n_last_bits = this->_num_bits & (BITSET_SIZE - 1);
if ( n_last_bits == 0 )
this->_mask_last = ~0;
else
this->_mask_last = (1 << n_last_bits) - 1;
this->clear_data();
}
void BitSet::clear()
{
this->resize(1);
}
void BitSet::clear_data()
{
for(uint32_t i = 0;i < this->_size_byte; ++i)
this->_data[i] = 0;
}
void BitSet::set_bit(uint32_t bit_number)
{
if (bit_number >= this->_num_bits)
{
ERR_PRINTS("[BitSet::set_bit] Out of range (size:" + itos(this->_size_byte) + ", pos:" + itos(bit_number) + ")" );
throw "Out of range";
}
uint32_t mask = bit_number & (BITSET_SIZE - 1);
mask = 1 << mask;
this->_data[bit_number>>5] |= mask;
}
void BitSet::clear_bit(uint32_t bit_number)
{
if (bit_number >= this->_num_bits)
{
ERR_PRINTS("[BitSet::clear_bit] Out of range (size:" + itos(this->_size_byte) + ", pos:" + itos(bit_number) + ")" );
throw "Out of range";
}
uint32_t mask = bit_number & (BITSET_SIZE - 1);
mask = 1 << mask;
this->_data[bit_number>>5] &= mask;
}
void BitSet::put(uint32_t bit_number, bool value)
{
if (bit_number >= this->_num_bits)
{
ERR_PRINTS("[BitSet::put] Out of range (size:" + itos(this->_size_byte) + ", pos:" + itos(bit_number) + ")" );
throw "Out of range";
}
if ( value == true )
this->set_bit(bit_number);
else
this->clear_bit(bit_number);
}
bool BitSet::get(uint32_t bit_number)
{
if (bit_number >= this->_num_bits)
{
ERR_PRINTS("[BitSet::get] Out of range (size:" + itos(this->_size_byte) + ", pos:" + itos(bit_number) + ")" );
throw "Out of range";
}
uint32_t mask = bit_number & (BITSET_SIZE - 1);
mask = 1 << mask;
return (this->_data[bit_number>>5] & mask) != 0;
}
void BitSet::write_serial(Ref<BitStream> msgout)
{
uint8_t current_version = 0;
msgout->put_uint8(current_version);
msgout->put_uint32(this->_num_bits);
// _size_byte est lié à _num_bits dommage que l'on envoie celui-la
msgout->put_uint32(this->_size_byte);
for(uint32_t i = 0;i < this->_size_byte; ++i)
msgout->put_uint32(this->_data[i]);
}
void BitSet::read_serial(Ref<BitStream> msgin)
{
uint8_t current_version = msgin->get_sint8();
uint8_t num_bits;
switch ( current_version )
{
case 0:
num_bits = msgin->get_uint32();
this->resize(num_bits);
for(uint32_t i = 0;i < this->_size_byte; ++i)
this->_data[i] = msgin->get_uint32();
break;
default:
ERR_PRINTS("[BitSet::read_serial] Unknown version: " + itos(current_version));
throw "Unknown version";
break;
}
}
String BitSet::show()
{
Ref<BitStream> msgout;
msgout.instance();
this->write_serial(msgout);
return msgout->show();
}

52
modules/bitset/bitset.h Normal file
View file

@ -0,0 +1,52 @@
/*
Header BitSet
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 BIT_SET_H
#define BIT_SET_H
#include "core/reference.h"
#include "modules/bitstream/bitstream.h"
class BitSet : public Reference {
GDCLASS(BitSet, Reference)
protected:
static void _bind_methods();
private:
uint32_t _num_bits;
uint32_t _size_byte;
uint32_t _mask_last;
uint32_t * _data;
public:
BitSet();
~BitSet();
int size();
void resize(uint32_t num_bits);
void clear();
void clear_data();
void set_bit(uint32_t bit_number);
void clear_bit(uint32_t bit_number);
void put(uint32_t bit_number, bool value);
bool get(uint32_t bit_number);
void write_serial(Ref<BitStream> msgout);
void read_serial(Ref<BitStream> msgin);
String show();
};
#endif

15
modules/bitset/config.py Normal file
View file

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

View file

@ -0,0 +1,87 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="BitSet" inherits="Reference" category="Core" version="3.1.2">
<brief_description>
</brief_description>
<description>
</description>
<tutorials>
</tutorials>
<methods>
<method name="clear">
<return type="void">
</return>
<description>
</description>
</method>
<method name="clear_bit">
<return type="void">
</return>
<argument index="0" name="bit_number" type="int">
</argument>
<description>
</description>
</method>
<method name="clear_data">
<return type="void">
</return>
<description>
</description>
</method>
<method name="put">
<return type="void">
</return>
<argument index="0" name="bit_number" type="int">
</argument>
<argument index="1" name="value" type="bool">
</argument>
<description>
</description>
</method>
<method name="read_serial">
<return type="void">
</return>
<argument index="0" name="msgin" type="BitStream">
</argument>
<description>
</description>
</method>
<method name="resize">
<return type="void">
</return>
<argument index="0" name="num_bits" type="int">
</argument>
<description>
</description>
</method>
<method name="set_bit">
<return type="void">
</return>
<argument index="0" name="bit_number" type="int">
</argument>
<description>
</description>
</method>
<method name="show">
<return type="String">
</return>
<description>
</description>
</method>
<method name="size">
<return type="int">
</return>
<description>
</description>
</method>
<method name="write_serial">
<return type="void">
</return>
<argument index="0" name="msgout" type="BitStream">
</argument>
<description>
</description>
</method>
</methods>
<constants>
</constants>
</class>

View file

@ -0,0 +1,14 @@
/* register_types.cpp */
#include "register_types.h"
#include "core/class_db.h"
#include "bitset.h"
void register_bitset_types() {
ClassDB::register_class<BitSet>();
}
void unregister_bitset_types() {
// Nothing to do here in this example.
}

View file

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

5
modules/bitstream/SCsub Normal file
View file

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

View file

@ -0,0 +1,456 @@
/*
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/>.
Build :
scons platform=linux bits=64
*/
#include "bitstream.h"
// TODO - check if on godot we have a function or variable to get if processor is little_endian or not
bool little_endian = false;
void BitStream::_bind_methods()
{
BitStream::init();
ClassDB::bind_method(D_METHOD("is_little_endian"), &BitStream::is_little_endian);
ClassDB::bind_method(D_METHOD("size"), &BitStream::size);
ClassDB::bind_method(D_METHOD("put_serial", "value", "nbits"), &BitStream::put_serial);
ClassDB::bind_method(D_METHOD("put_bool", "value"), &BitStream::put_bool);
ClassDB::bind_method(D_METHOD("put_char", "value"), &BitStream::put_char);
ClassDB::bind_method(D_METHOD("put_uint8", "value"), &BitStream::put_uint8);
ClassDB::bind_method(D_METHOD("put_sint8", "value"), &BitStream::put_sint8);
ClassDB::bind_method(D_METHOD("put_sint16", "value"), &BitStream::put_sint16);
ClassDB::bind_method(D_METHOD("put_uint16", "value"), &BitStream::put_uint16);
ClassDB::bind_method(D_METHOD("put_sint32", "value"), &BitStream::put_sint32);
ClassDB::bind_method(D_METHOD("put_uint32", "value"), &BitStream::put_uint32);
ClassDB::bind_method(D_METHOD("put_sint64", "value"), &BitStream::put_sint64);
ClassDB::bind_method(D_METHOD("put_uint64", "value"), &BitStream::put_uint64);
ClassDB::bind_method(D_METHOD("put_string", "value"), &BitStream::put_string);
ClassDB::bind_method(D_METHOD("put_string_hexa32", "hexa"), &BitStream::put_string_hexa32);
ClassDB::bind_method(D_METHOD("put_array_uint8", "value"), &BitStream::put_array_uint8);
ClassDB::bind_method(D_METHOD("show"), &BitStream::show);
ClassDB::bind_method(D_METHOD("show_detail"), &BitStream::show_detail);
ClassDB::bind_method(D_METHOD("show_counter"), &BitStream::show_counter);
ClassDB::bind_method(D_METHOD("get_data"), &BitStream::get_data);
ClassDB::bind_method(D_METHOD("put_data", "value"), &BitStream::put_data);
ClassDB::bind_method(D_METHOD("get_serial", "nbits"), &BitStream::get_serial);
ClassDB::bind_method(D_METHOD("get_bool"), &BitStream::get_bool);
ClassDB::bind_method(D_METHOD("get_sint8"), &BitStream::get_sint8);
ClassDB::bind_method(D_METHOD("get_uint8"), &BitStream::get_uint8);
ClassDB::bind_method(D_METHOD("get_sint16"), &BitStream::get_sint16);
ClassDB::bind_method(D_METHOD("get_uint16"), &BitStream::get_uint16);
ClassDB::bind_method(D_METHOD("get_sint32"), &BitStream::get_sint32);
ClassDB::bind_method(D_METHOD("get_uint32"), &BitStream::get_uint32);
ClassDB::bind_method(D_METHOD("get_sint64"), &BitStream::get_sint64);
ClassDB::bind_method(D_METHOD("get_uint64"), &BitStream::get_uint64);
ClassDB::bind_method(D_METHOD("get_array_uint8", "length"), &BitStream::get_array_uint8);
}
void BitStream::clear()
{
this->_pos = 0;
this->_read = 0;
}
BitStream::BitStream()
{
clear();
}
BitStream::~BitStream()
{
// add your cleanup here
}
void BitStream::init()
{
uint32_t i=0x12345678;
if ( (*((uint8_t*)(&i))) == 0x78 )
little_endian = true;
else
little_endian = false;
}
bool BitStream::is_little_endian()
{
return little_endian;
}
int BitStream::size()
{
return (this->_pos + 7) / 8;
}
int BitStream::size_data()
{
return this->_pos;
}
void BitStream::put_serial(uint32_t value, uint32_t nbits)
{
uint32_t v;
uint32_t mask;
uint32_t freeBits;
uint32_t pos;
if ( nbits == 0 )
return;
else if ( nbits > 32 )
throw "Out of range";
if ( this->_pos % 8 == 0 ) // Increase node
this->_data.append(0);
if ( nbits != 32 )
{
mask = (1 << nbits) - 1;
v = value & mask;
}
else
{
v = value;
}
freeBits = 8 - (this->_pos % 8);
pos = this->_data.size() - 1;
if(nbits > freeBits)
{
this->_data.set(pos, this->_data[pos] | (v >> (nbits - freeBits)));
this->_pos += freeBits;
this->put_serial(v, nbits - freeBits);
}
else
{
this->_data.set(pos, this->_data[pos] | (v << (freeBits - nbits)));
this->_pos += nbits;
}
}
void BitStream::put_bool(bool value)
{
this->put_serial(value, 1);
}
void BitStream::put_sint8(int8_t value)
{
this->put_serial(value, 8);
}
void BitStream::put_uint8(uint8_t value)
{
this->put_serial(value, 8);
}
void BitStream::put_sint16(int16_t value)
{
this->put_serial(value, 16);
}
void BitStream::put_uint16(uint16_t value)
{
this->put_serial(value, 16);
}
void BitStream::put_sint32(int32_t value)
{
this->put_serial(value, 32);
}
void BitStream::put_uint32(uint32_t value)
{
this->put_serial(value, 32);
}
void BitStream::put_sint64(int64_t value)
{
if(little_endian)
{
this->put_serial(value>>32, 32);
this->put_serial(value, 32);
}
else
{
this->put_serial(value, 32);
this->put_serial(value>>32, 32);
}
}
void BitStream::put_uint64(uint64_t value)
{
if(little_endian)
{
this->put_serial(value>>32, 32);
this->put_serial(value, 32);
}
else
{
this->put_serial(value, 32);
this->put_serial(value>>32, 32);
}
}
void BitStream::put_string_hexa32(String hexa)
{
uint32_t res = 0;
CharString tmp = hexa.ascii();
for(const char * c = tmp.get_data(); *c != 0; c++)
{
res <<= 4;
if ( *c >= '0' && *c <= '9')
res += *c - '0';
else if ( *c >= 'A' && *c <= 'F')
res += *c - 'A' + 10;
}
this->put_serial(res,32);
}
void BitStream::put_char(String value)
{
if ( value.length() >= 1)
this->put_uint8( value[0] );
else
this->put_uint8( 0 );
}
void BitStream::put_string(String value)
{
CharString data = value.ascii();
int lenvalue = data.size() - 1;
this->put_uint32(lenvalue);
for(int i = 0; i < lenvalue; ++i)
{
this->put_uint8(data[i]);
}
}
void BitStream::put_array_uint8(PoolByteArray value)
{
for(int i = 0; i < value.size() ; ++i)
this->put_serial(value[i], 8);
}
String BitStream::show()
{
String ret;
uint32_t pos = 0;
for(int i = 0; i < this->_data.size(); ++i)
{
uint8_t c = this->_data[i];
uint8_t mask = 0x80;
while(mask)
{
if ( (c & mask) != 0 )
ret += String("1");
else
ret += String("0");
mask >>= 1;
pos += 1;
if (pos >= this->_pos)
break;
}
if (pos >= this->_pos)
break;
}
return ret ;
}
String BitStream::show_detail()
{
String ret;
uint32_t pos = 0;
for(int i = 0; i < this->_data.size(); ++i)
{
uint8_t c = this->_data[i];
uint8_t mask = 0x80;
while(mask)
{
if ( (c & mask) != 0 )
ret += String("1");
else
ret += String("0");
mask >>= 1;
pos += 1;
if (pos >= this->_pos)
break;
}
if (pos >= this->_pos)
break;
}
String strsize;
uint32_t t = this->_data.size();
if ( t == 0) strsize = "0";
while ( t > 0 )
{
const char c = '0' + ( t % 10 );
strsize = String(&c) + strsize;
t /= 10;
}
String strpos;
t = this->_pos;
if ( t == 0) strpos = "0";
while ( t > 0 )
{
const char c = '0' + ( t % 10 );
strpos = String(&c) + strpos;
t /= 10;
}
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()
{
return this->_data;
}
void BitStream::put_data(PoolByteArray value)
{
this->_data = value;
this->_pos = value.size() * 8;
}
uint32_t BitStream::get_serial(uint32_t nbits)
{
uint32_t value;
uint32_t pos;
uint32_t freeBits;
uint32_t v;
if ( nbits == 0 )
return 0;
else if ( nbits > 32 )
{
ERR_PRINT("Out of range (BitStream::get_serial)");
throw "Out of range";
}
if (this->_read + nbits > this->_pos)
{
ERR_PRINT("Out of range (BitStream::get_serial)");
throw "Out of range";
}
value = 0;
pos = this->_read / 8;
freeBits = 8 - (this->_read % 8);
v = this->_data[pos] & ((1 << freeBits) - 1);
if(nbits > freeBits)
{
value |= (v << (nbits-freeBits));
this->_read += freeBits;
value |= this->get_serial(nbits - freeBits);
}
else
{
value |= (v >> (freeBits-nbits));
this->_read += nbits;
}
return value;
}
bool BitStream::get_bool()
{
if(this->get_serial(1) == 0)
return false;
return true;
}
int8_t BitStream::get_sint8()
{
return this->get_serial(8);
}
uint8_t BitStream::get_uint8()
{
return this->get_serial(8);
}
int16_t BitStream::get_sint16()
{
return this->get_serial(16);
}
uint16_t BitStream::get_uint16()
{
return this->get_serial(16);
}
int32_t BitStream::get_sint32()
{
return this->get_serial(32);
}
uint32_t BitStream::get_uint32()
{
return this->get_serial(32);
}
int64_t BitStream::get_sint64()
{
int64_t v1;
int64_t v2;
if(little_endian)
{
v1 = this->get_serial(32);
v2 = this->get_serial(32);
}
else
{
v2 = this->get_serial(32);
v1 = this->get_serial(32);
}
return (v1 << 32) | v2;
}
uint64_t BitStream::get_uint64()
{
int64_t v1;
int64_t v2;
if(little_endian)
{
v1 = this->get_serial(32);
v2 = this->get_serial(32);
}
else
{
v2 = this->get_serial(32);
v1 = this->get_serial(32);
}
return (v1 << 32) | v2;
}
PoolByteArray BitStream::get_array_uint8(uint32_t length)
{
PoolByteArray ret;
while(length != 0)
{
ret.append(this->get_serial(8));
--length;
}
return ret;
}

View file

@ -0,0 +1,81 @@
/*
Header BitStream
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 BIT_STREAM_H
#define BIT_STREAM_H
#include "core/reference.h"
class BitStream : public Reference {
GDCLASS(BitStream, Reference)
protected:
static void _bind_methods();
private:
uint32_t _pos;
uint32_t _read;
PoolByteArray _data;
public:
void clear();
BitStream();
~BitStream();
static void init(); // our initializer called by Godot
bool is_little_endian();
int size();
int size_data();
void put_serial(uint32_t value, uint32_t nbits);
void put_bool(bool value);
void put_sint8(int8_t value);
void put_uint8(uint8_t value);
void put_sint16(int16_t value);
void put_uint16(uint16_t value);
void put_sint32(int32_t value);
void put_uint32(uint32_t value);
void put_sint64(int64_t value);
void put_uint64(uint64_t value);
void put_string_hexa32(String hexa);
void put_char(String value);
void put_string(String value);
void put_array_uint8(PoolByteArray value);
String show();
String show_detail();
String show_counter();
PoolByteArray get_data();
void put_data(PoolByteArray value);
uint32_t get_serial(uint32_t nbits);
bool get_bool();
int8_t get_sint8();
uint8_t get_uint8();
int16_t get_sint16();
uint16_t get_uint16();
int32_t get_sint32();
uint32_t get_uint32();
int64_t get_sint64();
uint64_t get_uint64();
PoolByteArray get_array_uint8(uint32_t length);
};
#endif

View file

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

View file

@ -0,0 +1,241 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="BitStream" inherits="Reference" category="Core" version="3.1.2">
<brief_description>
</brief_description>
<description>
</description>
<tutorials>
</tutorials>
<methods>
<method name="get_array_uint8">
<return type="PoolByteArray">
</return>
<argument index="0" name="length" type="int">
</argument>
<description>
</description>
</method>
<method name="get_bool">
<return type="bool">
</return>
<description>
</description>
</method>
<method name="get_data">
<return type="PoolByteArray">
</return>
<description>
</description>
</method>
<method name="get_serial">
<return type="int">
</return>
<argument index="0" name="nbits" type="int">
</argument>
<description>
</description>
</method>
<method name="get_sint16">
<return type="int">
</return>
<description>
</description>
</method>
<method name="get_sint32">
<return type="int">
</return>
<description>
</description>
</method>
<method name="get_sint64">
<return type="int">
</return>
<description>
</description>
</method>
<method name="get_sint8">
<return type="int">
</return>
<description>
</description>
</method>
<method name="get_uint16">
<return type="int">
</return>
<description>
</description>
</method>
<method name="get_uint32">
<return type="int">
</return>
<description>
</description>
</method>
<method name="get_uint64">
<return type="int">
</return>
<description>
</description>
</method>
<method name="get_uint8">
<return type="int">
</return>
<description>
</description>
</method>
<method name="is_little_endian">
<return type="bool">
</return>
<description>
</description>
</method>
<method name="put_array_uint8">
<return type="void">
</return>
<argument index="0" name="value" type="PoolByteArray">
</argument>
<description>
</description>
</method>
<method name="put_bool">
<return type="void">
</return>
<argument index="0" name="value" type="bool">
</argument>
<description>
</description>
</method>
<method name="put_char">
<return type="void">
</return>
<argument index="0" name="value" type="String">
</argument>
<description>
</description>
</method>
<method name="put_data">
<return type="void">
</return>
<argument index="0" name="value" type="PoolByteArray">
</argument>
<description>
</description>
</method>
<method name="put_serial">
<return type="void">
</return>
<argument index="0" name="value" type="int">
</argument>
<argument index="1" name="nbits" type="int">
</argument>
<description>
</description>
</method>
<method name="put_sint16">
<return type="void">
</return>
<argument index="0" name="value" type="int">
</argument>
<description>
</description>
</method>
<method name="put_sint32">
<return type="void">
</return>
<argument index="0" name="value" type="int">
</argument>
<description>
</description>
</method>
<method name="put_sint64">
<return type="void">
</return>
<argument index="0" name="value" type="int">
</argument>
<description>
</description>
</method>
<method name="put_sint8">
<return type="void">
</return>
<argument index="0" name="value" type="int">
</argument>
<description>
</description>
</method>
<method name="put_string">
<return type="void">
</return>
<argument index="0" name="value" type="String">
</argument>
<description>
</description>
</method>
<method name="put_string_hexa32">
<return type="void">
</return>
<argument index="0" name="hexa" type="String">
</argument>
<description>
</description>
</method>
<method name="put_uint16">
<return type="void">
</return>
<argument index="0" name="value" type="int">
</argument>
<description>
</description>
</method>
<method name="put_uint32">
<return type="void">
</return>
<argument index="0" name="value" type="int">
</argument>
<description>
</description>
</method>
<method name="put_uint64">
<return type="void">
</return>
<argument index="0" name="value" type="int">
</argument>
<description>
</description>
</method>
<method name="put_uint8">
<return type="void">
</return>
<argument index="0" name="value" type="int">
</argument>
<description>
</description>
</method>
<method name="show">
<return type="String">
</return>
<description>
</description>
</method>
<method name="show_counter">
<return type="String">
</return>
<description>
</description>
</method>
<method name="show_detail">
<return type="String">
</return>
<description>
</description>
</method>
<method name="size">
<return type="int">
</return>
<description>
</description>
</method>
</methods>
<constants>
</constants>
</class>

View file

@ -0,0 +1,14 @@
/* register_types.cpp */
#include "register_types.h"
#include "core/class_db.h"
#include "bitstream.h"
void register_bitstream_types() {
ClassDB::register_class<BitStream>();
}
void unregister_bitstream_types() {
// Nothing to do here in this example.
}

View file

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

View file

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

View file

@ -0,0 +1,144 @@
/*
BitStreamQueue : class to manage packet received by server
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 "bitstreamqueue.h"
#include "core/os/os.h"
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);
}
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->clear();
}
BitStreamQueue::~BitStreamQueue()
{
OS::get_singleton()->print("[%s:%d] delete BitStreamQueue\n", __FILE__, __LINE__);
for(int i = 0 ; i < SIZE_QUEUE_MESSAGE ; ++i )
this->_msgin[i].unref();
for(int i = 0 ; i < SIZE_QUEUE_MESSAGE ; ++i )
{
if (this->_msgin[i].unref())
/*
{
OS::get_singleton()->print("[%s:%d] delete BitStreamQueue %d\n", __FILE__, __LINE__, i);
memdelete(this->_msgin[i]);
this->_msgin[i] = nullptr;
}
*/
}
}
void BitStreamQueue::clear()
{
for(int i = 0 ; i < SIZE_QUEUE_MESSAGE ; ++i )
{
this->_received_number[i] = 0;
this->_msgin[i]->clear();
}
this->_size = 0;
}
int BitStreamQueue::length()
{
return this->_size;
}
int BitStreamQueue::put_msgbytes(PoolByteArray msgbytes)
{
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
{
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;
// 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 ++;
return i;
}
Ref<BitStream> BitStreamQueue::get_msg(int pos)
{
//Ref<BitStream> ret;
if ( pos >= SIZE_QUEUE_MESSAGE )
{
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];
}
uint32_t BitStreamQueue::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 BitStreamQueue::erase(int pos)
{
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 -- ;
}

View file

@ -0,0 +1,50 @@
/*
Header BitStreamQueue : Manage message received
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 BIT_STREAM_QUEUE_H
#define BIT_STREAM_QUEUE_H
#define SIZE_QUEUE_MESSAGE 6
#include "core/reference.h"
#include "modules/bitstream/bitstream.h"
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[SIZE_QUEUE_MESSAGE];
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);
};
#endif // BIT_STREAM_QUEUE_H

View file

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

View file

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="BitStreamQueue" inherits="Reference" category="Core" version="3.1.2">
<brief_description>
</brief_description>
<description>
</description>
<tutorials>
</tutorials>
<methods>
<method name="clear">
<return type="void">
</return>
<description>
</description>
</method>
<method name="erase">
<return type="void">
</return>
<argument index="0" name="pos" type="int">
</argument>
<description>
</description>
</method>
<method name="get_msg">
<return type="BitStream">
</return>
<argument index="0" name="pos" type="int">
</argument>
<description>
</description>
</method>
<method name="get_received_number">
<return type="int">
</return>
<argument index="0" name="pos" type="int">
</argument>
<description>
</description>
</method>
<method name="length">
<return type="int">
</return>
<description>
</description>
</method>
<method name="put_msgbytes">
<return type="int">
</return>
<argument index="0" name="msgbytes" type="PoolByteArray">
</argument>
<description>
</description>
</method>
</methods>
<constants>
</constants>
</class>

View file

@ -0,0 +1,14 @@
/* register_types.cpp */
#include "register_types.h"
#include "core/class_db.h"
#include "bitstreamqueue.h"
void register_bitstreamqueue_types() {
ClassDB::register_class<BitStreamQueue>();
}
void unregister_bitstreamqueue_types() {
// Nothing to do here in this example.
}

View file

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

5
modules/crypt/SCsub Normal file
View file

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

15
modules/crypt/config.py Normal file
View file

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

30
modules/crypt/crypt.cpp Normal file
View file

@ -0,0 +1,30 @@
/*
Module to encrypt message with sha512 method
*/
#include "crypt.h"
#include "sha512crypt.h"
void Crypt::_bind_methods() {
ClassDB::bind_method(D_METHOD("encrypt", "key", "salt") , &Crypt::encrypt);
}
Crypt::Crypt() {
}
Crypt::~Crypt() {
// add your cleanup here
}
void Crypt::_init() {
// initialize any variables here
}
String Crypt::encrypt(String key, String salt) {
String out = "";
char * res = sha512_crypt (key.ascii().get_data(), salt.ascii().get_data());
out = res;
return out;
}

23
modules/crypt/crypt.h Normal file
View file

@ -0,0 +1,23 @@
#ifndef CRYPT_H
#define CRYPT_H
#include "core/reference.h"
class Crypt : public Reference {
GDCLASS(Crypt, Reference)
protected:
static void _bind_methods();
public:
static void _register_methods();
Crypt();
~Crypt();
void _init(); // our initializer called by Godot
String encrypt(String key, String salt);
};
#endif

View file

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Crypt" inherits="Reference" category="Core" version="3.1.2">
<brief_description>
</brief_description>
<description>
</description>
<tutorials>
</tutorials>
<methods>
<method name="encrypt">
<return type="String">
</return>
<argument index="0" name="key" type="String">
</argument>
<argument index="1" name="salt" type="String">
</argument>
<description>
</description>
</method>
</methods>
<constants>
</constants>
</class>

View file

@ -0,0 +1,14 @@
/* register_types.cpp */
#include "register_types.h"
#include "core/class_db.h"
#include "crypt.h"
void register_crypt_types() {
ClassDB::register_class<Crypt>();
}
void unregister_crypt_types() {
// Nothing to do here in this example.
}

View file

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

View file

@ -0,0 +1,622 @@
/* SHA512-based Unix crypt implementation.
Released into the Public Domain by Ulrich Drepper <drepper@redhat.com>. */
#include <endian.h>
#include <errno.h>
#include <limits.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/param.h>
#include <sys/types.h>
/* Structure to save state of computation between the single steps. */
struct sha512_ctx
{
uint64_t H[8];
uint64_t total[2];
uint64_t buflen;
char buffer[256]; /* NB: always correctly aligned for uint64_t. */
};
#if __BYTE_ORDER == __LITTLE_ENDIAN
# define SWAP(n) \
(((n) << 56) \
| (((n) & 0xff00) << 40) \
| (((n) & 0xff0000) << 24) \
| (((n) & 0xff000000) << 8) \
| (((n) >> 8) & 0xff000000) \
| (((n) >> 24) & 0xff0000) \
| (((n) >> 40) & 0xff00) \
| ((n) >> 56))
#else
# define SWAP(n) (n)
#endif
/* This array contains the bytes used to pad the buffer to the next
64-byte boundary. (FIPS 180-2:5.1.2) */
static const unsigned char fillbuf[128] = { 0x80, 0 /* , 0, 0, ... */ };
/* Constants for SHA512 from FIPS 180-2:4.2.3. */
static const uint64_t K[80] =
{
UINT64_C (0x428a2f98d728ae22), UINT64_C (0x7137449123ef65cd),
UINT64_C (0xb5c0fbcfec4d3b2f), UINT64_C (0xe9b5dba58189dbbc),
UINT64_C (0x3956c25bf348b538), UINT64_C (0x59f111f1b605d019),
UINT64_C (0x923f82a4af194f9b), UINT64_C (0xab1c5ed5da6d8118),
UINT64_C (0xd807aa98a3030242), UINT64_C (0x12835b0145706fbe),
UINT64_C (0x243185be4ee4b28c), UINT64_C (0x550c7dc3d5ffb4e2),
UINT64_C (0x72be5d74f27b896f), UINT64_C (0x80deb1fe3b1696b1),
UINT64_C (0x9bdc06a725c71235), UINT64_C (0xc19bf174cf692694),
UINT64_C (0xe49b69c19ef14ad2), UINT64_C (0xefbe4786384f25e3),
UINT64_C (0x0fc19dc68b8cd5b5), UINT64_C (0x240ca1cc77ac9c65),
UINT64_C (0x2de92c6f592b0275), UINT64_C (0x4a7484aa6ea6e483),
UINT64_C (0x5cb0a9dcbd41fbd4), UINT64_C (0x76f988da831153b5),
UINT64_C (0x983e5152ee66dfab), UINT64_C (0xa831c66d2db43210),
UINT64_C (0xb00327c898fb213f), UINT64_C (0xbf597fc7beef0ee4),
UINT64_C (0xc6e00bf33da88fc2), UINT64_C (0xd5a79147930aa725),
UINT64_C (0x06ca6351e003826f), UINT64_C (0x142929670a0e6e70),
UINT64_C (0x27b70a8546d22ffc), UINT64_C (0x2e1b21385c26c926),
UINT64_C (0x4d2c6dfc5ac42aed), UINT64_C (0x53380d139d95b3df),
UINT64_C (0x650a73548baf63de), UINT64_C (0x766a0abb3c77b2a8),
UINT64_C (0x81c2c92e47edaee6), UINT64_C (0x92722c851482353b),
UINT64_C (0xa2bfe8a14cf10364), UINT64_C (0xa81a664bbc423001),
UINT64_C (0xc24b8b70d0f89791), UINT64_C (0xc76c51a30654be30),
UINT64_C (0xd192e819d6ef5218), UINT64_C (0xd69906245565a910),
UINT64_C (0xf40e35855771202a), UINT64_C (0x106aa07032bbd1b8),
UINT64_C (0x19a4c116b8d2d0c8), UINT64_C (0x1e376c085141ab53),
UINT64_C (0x2748774cdf8eeb99), UINT64_C (0x34b0bcb5e19b48a8),
UINT64_C (0x391c0cb3c5c95a63), UINT64_C (0x4ed8aa4ae3418acb),
UINT64_C (0x5b9cca4f7763e373), UINT64_C (0x682e6ff3d6b2b8a3),
UINT64_C (0x748f82ee5defb2fc), UINT64_C (0x78a5636f43172f60),
UINT64_C (0x84c87814a1f0ab72), UINT64_C (0x8cc702081a6439ec),
UINT64_C (0x90befffa23631e28), UINT64_C (0xa4506cebde82bde9),
UINT64_C (0xbef9a3f7b2c67915), UINT64_C (0xc67178f2e372532b),
UINT64_C (0xca273eceea26619c), UINT64_C (0xd186b8c721c0c207),
UINT64_C (0xeada7dd6cde0eb1e), UINT64_C (0xf57d4f7fee6ed178),
UINT64_C (0x06f067aa72176fba), UINT64_C (0x0a637dc5a2c898a6),
UINT64_C (0x113f9804bef90dae), UINT64_C (0x1b710b35131c471b),
UINT64_C (0x28db77f523047d84), UINT64_C (0x32caab7b40c72493),
UINT64_C (0x3c9ebe0a15c9bebc), UINT64_C (0x431d67c49c100d4c),
UINT64_C (0x4cc5d4becb3e42b6), UINT64_C (0x597f299cfc657e2a),
UINT64_C (0x5fcb6fab3ad6faec), UINT64_C (0x6c44198c4a475817)
};
/* Process LEN bytes of BUFFER, accumulating context into CTX.
It is assumed that LEN % 128 == 0. */
static void
sha512_process_block (const void *buffer, size_t len, struct sha512_ctx *ctx)
{
const uint64_t *words = (uint64_t *)buffer;
size_t nwords = len / sizeof (uint64_t);
uint64_t a = ctx->H[0];
uint64_t b = ctx->H[1];
uint64_t c = ctx->H[2];
uint64_t d = ctx->H[3];
uint64_t e = ctx->H[4];
uint64_t f = ctx->H[5];
uint64_t g = ctx->H[6];
uint64_t h = ctx->H[7];
/* First increment the byte count. FIPS 180-2 specifies the possible
length of the file up to 2^128 bits. Here we only compute the
number of bytes. Do a double word increment. */
ctx->total[0] += len;
if (ctx->total[0] < len)
++ctx->total[1];
/* Process all bytes in the buffer with 128 bytes in each round of
the loop. */
while (nwords > 0)
{
uint64_t W[80];
uint64_t a_save = a;
uint64_t b_save = b;
uint64_t c_save = c;
uint64_t d_save = d;
uint64_t e_save = e;
uint64_t f_save = f;
uint64_t g_save = g;
uint64_t h_save = h;
/* Operators defined in FIPS 180-2:4.1.2. */
#define Ch(x, y, z) ((x & y) ^ (~x & z))
#define Maj(x, y, z) ((x & y) ^ (x & z) ^ (y & z))
#define S0(x) (CYCLIC (x, 28) ^ CYCLIC (x, 34) ^ CYCLIC (x, 39))
#define S1(x) (CYCLIC (x, 14) ^ CYCLIC (x, 18) ^ CYCLIC (x, 41))
#define R0(x) (CYCLIC (x, 1) ^ CYCLIC (x, 8) ^ (x >> 7))
#define R1(x) (CYCLIC (x, 19) ^ CYCLIC (x, 61) ^ (x >> 6))
/* It is unfortunate that C does not provide an operator for
cyclic rotation. Hope the C compiler is smart enough. */
#define CYCLIC(w, s) ((w >> s) | (w << (64 - s)))
/* Compute the message schedule according to FIPS 180-2:6.3.2 step 2. */
for (unsigned int t = 0; t < 16; ++t)
{
W[t] = SWAP (*words);
++words;
}
for (unsigned int t = 16; t < 80; ++t)
W[t] = R1 (W[t - 2]) + W[t - 7] + R0 (W[t - 15]) + W[t - 16];
/* The actual computation according to FIPS 180-2:6.3.2 step 3. */
for (unsigned int t = 0; t < 80; ++t)
{
uint64_t T1 = h + S1 (e) + Ch (e, f, g) + K[t] + W[t];
uint64_t T2 = S0 (a) + Maj (a, b, c);
h = g;
g = f;
f = e;
e = d + T1;
d = c;
c = b;
b = a;
a = T1 + T2;
}
/* Add the starting values of the context according to FIPS 180-2:6.3.2
step 4. */
a += a_save;
b += b_save;
c += c_save;
d += d_save;
e += e_save;
f += f_save;
g += g_save;
h += h_save;
/* Prepare for the next round. */
nwords -= 16;
}
/* Put checksum in context given as argument. */
ctx->H[0] = a;
ctx->H[1] = b;
ctx->H[2] = c;
ctx->H[3] = d;
ctx->H[4] = e;
ctx->H[5] = f;
ctx->H[6] = g;
ctx->H[7] = h;
}
/* Initialize structure containing state of computation.
(FIPS 180-2:5.3.3) */
static void
sha512_init_ctx (struct sha512_ctx *ctx)
{
ctx->H[0] = UINT64_C (0x6a09e667f3bcc908);
ctx->H[1] = UINT64_C (0xbb67ae8584caa73b);
ctx->H[2] = UINT64_C (0x3c6ef372fe94f82b);
ctx->H[3] = UINT64_C (0xa54ff53a5f1d36f1);
ctx->H[4] = UINT64_C (0x510e527fade682d1);
ctx->H[5] = UINT64_C (0x9b05688c2b3e6c1f);
ctx->H[6] = UINT64_C (0x1f83d9abfb41bd6b);
ctx->H[7] = UINT64_C (0x5be0cd19137e2179);
ctx->total[0] = ctx->total[1] = 0;
ctx->buflen = 0;
}
/* Process the remaining bytes in the internal buffer and the usual
prolog according to the standard and write the result to RESBUF.
IMPORTANT: On some systems it is required that RESBUF is correctly
aligned for a 32 bits value. */
static void *
sha512_finish_ctx (struct sha512_ctx *ctx, void *resbuf)
{
/* Take yet unprocessed bytes into account. */
uint64_t bytes = ctx->buflen;
size_t pad;
/* Now count remaining bytes. */
ctx->total[0] += bytes;
if (ctx->total[0] < bytes)
++ctx->total[1];
pad = bytes >= 112 ? 128 + 112 - bytes : 112 - bytes;
memcpy (&ctx->buffer[bytes], fillbuf, pad);
/* Put the 128-bit file length in *bits* at the end of the buffer. */
*(uint64_t *) &ctx->buffer[bytes + pad + 8] = SWAP (ctx->total[0] << 3);
*(uint64_t *) &ctx->buffer[bytes + pad] = SWAP ((ctx->total[1] << 3) |
(ctx->total[0] >> 61));
/* Process last bytes. */
sha512_process_block (ctx->buffer, bytes + pad + 16, ctx);
/* Put result from CTX in first 64 bytes following RESBUF. */
for (unsigned int i = 0; i < 8; ++i)
((uint64_t *) resbuf)[i] = SWAP (ctx->H[i]);
return resbuf;
}
static void
sha512_process_bytes (const void *buffer, size_t len, struct sha512_ctx *ctx)
{
/* When we already have some bits in our internal buffer concatenate
both inputs first. */
if (ctx->buflen != 0)
{
size_t left_over = ctx->buflen;
size_t add = 256 - left_over > len ? len : 256 - left_over;
memcpy (&ctx->buffer[left_over], buffer, add);
ctx->buflen += add;
if (ctx->buflen > 128)
{
sha512_process_block (ctx->buffer, ctx->buflen & ~127, ctx);
ctx->buflen &= 127;
/* The regions in the following copy operation cannot overlap. */
memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~127],
ctx->buflen);
}
buffer = (const char *) buffer + add;
len -= add;
}
/* Process available complete blocks. */
if (len >= 128)
{
#if !_STRING_ARCH_unaligned
/* To check alignment gcc has an appropriate operator. Other
compilers don't. */
# if __GNUC__ >= 2
# define UNALIGNED_P(p) (((uintptr_t) p) % __alignof__ (uint64_t) != 0)
# else
# define UNALIGNED_P(p) (((uintptr_t) p) % sizeof (uint64_t) != 0)
# endif
if (UNALIGNED_P (buffer))
while (len > 128)
{
sha512_process_block (memcpy (ctx->buffer, buffer, 128), 128,
ctx);
buffer = (const char *) buffer + 128;
len -= 128;
}
else
#endif
{
sha512_process_block (buffer, len & ~127, ctx);
buffer = (const char *) buffer + (len & ~127);
len &= 127;
}
}
/* Move remaining bytes into internal buffer. */
if (len > 0)
{
size_t left_over = ctx->buflen;
memcpy (&ctx->buffer[left_over], buffer, len);
left_over += len;
if (left_over >= 128)
{
sha512_process_block (ctx->buffer, 128, ctx);
left_over -= 128;
memcpy (ctx->buffer, &ctx->buffer[128], left_over);
}
ctx->buflen = left_over;
}
}
/* Define our magic string to mark salt for SHA512 "encryption"
replacement. */
static const char sha512_salt_prefix[] = "$6$";
/* Prefix for optional rounds specification. */
static const char sha512_rounds_prefix[] = "rounds=";
/* Maximum salt string length. */
#define SALT_LEN_MAX 16
/* Default number of rounds if not explicitly specified. */
#define ROUNDS_DEFAULT 5000
/* Minimum number of rounds. */
#define ROUNDS_MIN 1000
/* Maximum number of rounds. */
#define ROUNDS_MAX 999999999
/* Table with characters for base64 transformation. */
static const char b64t[65] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
static char *
sha512_crypt_r (const char *key, const char *salt, char *buffer, int buflen)
{
unsigned char alt_result[64]
__attribute__ ((__aligned__ (__alignof__ (uint64_t))));
unsigned char temp_result[64]
__attribute__ ((__aligned__ (__alignof__ (uint64_t))));
struct sha512_ctx ctx;
struct sha512_ctx alt_ctx;
size_t salt_len;
size_t key_len;
size_t cnt;
char *cp;
char *copied_key = NULL;
char *copied_salt = NULL;
char *p_bytes;
char *s_bytes;
/* Default number of rounds. */
size_t rounds = ROUNDS_DEFAULT;
bool rounds_custom = false;
/* Find beginning of salt string. The prefix should normally always
be present. Just in case it is not. */
if (strncmp (sha512_salt_prefix, salt, sizeof (sha512_salt_prefix) - 1) == 0)
/* Skip salt prefix. */
salt += sizeof (sha512_salt_prefix) - 1;
if (strncmp (salt, sha512_rounds_prefix, sizeof (sha512_rounds_prefix) - 1)
== 0)
{
const char *num = salt + sizeof (sha512_rounds_prefix) - 1;
char *endp;
unsigned long int srounds = strtoul (num, &endp, 10);
if (*endp == '$')
{
salt = endp + 1;
rounds = MAX (ROUNDS_MIN, MIN (srounds, ROUNDS_MAX));
rounds_custom = true;
}
}
salt_len = MIN (strcspn (salt, "$"), SALT_LEN_MAX);
key_len = strlen (key);
if ((key - (char *) 0) % __alignof__ (uint64_t) != 0)
{
char *tmp = (char *) alloca (key_len + __alignof__ (uint64_t));
key = copied_key = (char *)
memcpy (tmp + __alignof__ (uint64_t)
- (tmp - (char *) 0) % __alignof__ (uint64_t),
key, key_len);
}
if ((salt - (char *) 0) % __alignof__ (uint64_t) != 0)
{
char *tmp = (char *) alloca (salt_len + __alignof__ (uint64_t));
salt = copied_salt = (char *)
memcpy (tmp + __alignof__ (uint64_t)
- (tmp - (char *) 0) % __alignof__ (uint64_t),
salt, salt_len);
}
/* Prepare for the real work. */
sha512_init_ctx (&ctx);
/* Add the key string. */
sha512_process_bytes (key, key_len, &ctx);
/* The last part is the salt string. This must be at most 16
characters and it ends at the first `$' character (for
compatibility with existing implementations). */
sha512_process_bytes (salt, salt_len, &ctx);
/* Compute alternate SHA512 sum with input KEY, SALT, and KEY. The
final result will be added to the first context. */
sha512_init_ctx (&alt_ctx);
/* Add key. */
sha512_process_bytes (key, key_len, &alt_ctx);
/* Add salt. */
sha512_process_bytes (salt, salt_len, &alt_ctx);
/* Add key again. */
sha512_process_bytes (key, key_len, &alt_ctx);
/* Now get result of this (64 bytes) and add it to the other
context. */
sha512_finish_ctx (&alt_ctx, alt_result);
/* Add for any character in the key one byte of the alternate sum. */
for (cnt = key_len; cnt > 64; cnt -= 64)
sha512_process_bytes (alt_result, 64, &ctx);
sha512_process_bytes (alt_result, cnt, &ctx);
/* Take the binary representation of the length of the key and for every
1 add the alternate sum, for every 0 the key. */
for (cnt = key_len; cnt > 0; cnt >>= 1)
if ((cnt & 1) != 0)
sha512_process_bytes (alt_result, 64, &ctx);
else
sha512_process_bytes (key, key_len, &ctx);
/* Create intermediate result. */
sha512_finish_ctx (&ctx, alt_result);
/* Start computation of P byte sequence. */
sha512_init_ctx (&alt_ctx);
/* For every character in the password add the entire password. */
for (cnt = 0; cnt < key_len; ++cnt)
sha512_process_bytes (key, key_len, &alt_ctx);
/* Finish the digest. */
sha512_finish_ctx (&alt_ctx, temp_result);
/* Create byte sequence P. */
cp = p_bytes = (char *)alloca (key_len);
for (cnt = key_len; cnt >= 64; cnt -= 64)
cp = (char *)mempcpy (cp, temp_result, 64);
memcpy (cp, temp_result, cnt);
/* Start computation of S byte sequence. */
sha512_init_ctx (&alt_ctx);
/* For every character in the password add the entire password. */
for (cnt = 0; cnt < 16 + alt_result[0]; ++cnt)
sha512_process_bytes (salt, salt_len, &alt_ctx);
/* Finish the digest. */
sha512_finish_ctx (&alt_ctx, temp_result);
/* Create byte sequence S. */
cp = s_bytes = (char *)alloca (salt_len);
for (cnt = salt_len; cnt >= 64; cnt -= 64)
cp = (char *)mempcpy ( cp, temp_result, 64);
memcpy (cp, temp_result, cnt);
/* Repeatedly run the collected hash value through SHA512 to burn
CPU cycles. */
for (cnt = 0; cnt < rounds; ++cnt)
{
/* New context. */
sha512_init_ctx (&ctx);
/* Add key or last result. */
if ((cnt & 1) != 0)
sha512_process_bytes (p_bytes, key_len, &ctx);
else
sha512_process_bytes (alt_result, 64, &ctx);
/* Add salt for numbers not divisible by 3. */
if (cnt % 3 != 0)
sha512_process_bytes (s_bytes, salt_len, &ctx);
/* Add key for numbers not divisible by 7. */
if (cnt % 7 != 0)
sha512_process_bytes (p_bytes, key_len, &ctx);
/* Add key or last result. */
if ((cnt & 1) != 0)
sha512_process_bytes (alt_result, 64, &ctx);
else
sha512_process_bytes (p_bytes, key_len, &ctx);
/* Create intermediate result. */
sha512_finish_ctx (&ctx, alt_result);
}
/* Now we can construct the result string. It consists of three
parts. */
cp = __stpncpy (buffer, sha512_salt_prefix, MAX (0, buflen));
buflen -= sizeof (sha512_salt_prefix) - 1;
if (rounds_custom)
{
int n = snprintf (cp, MAX (0, buflen), "%s%zu$",
sha512_rounds_prefix, rounds);
cp += n;
buflen -= n;
}
cp = __stpncpy (cp, salt, MIN ((size_t) MAX (0, buflen), salt_len));
buflen -= MIN ((size_t) MAX (0, buflen), salt_len);
if (buflen > 0)
{
*cp++ = '$';
--buflen;
}
#define b64_from_24bit(B2, B1, B0, N) \
do { \
unsigned int w = ((B2) << 16) | ((B1) << 8) | (B0); \
int n = (N); \
while (n-- > 0 && buflen > 0) \
{ \
*cp++ = b64t[w & 0x3f]; \
--buflen; \
w >>= 6; \
} \
} while (0)
b64_from_24bit (alt_result[0], alt_result[21], alt_result[42], 4);
b64_from_24bit (alt_result[22], alt_result[43], alt_result[1], 4);
b64_from_24bit (alt_result[44], alt_result[2], alt_result[23], 4);
b64_from_24bit (alt_result[3], alt_result[24], alt_result[45], 4);
b64_from_24bit (alt_result[25], alt_result[46], alt_result[4], 4);
b64_from_24bit (alt_result[47], alt_result[5], alt_result[26], 4);
b64_from_24bit (alt_result[6], alt_result[27], alt_result[48], 4);
b64_from_24bit (alt_result[28], alt_result[49], alt_result[7], 4);
b64_from_24bit (alt_result[50], alt_result[8], alt_result[29], 4);
b64_from_24bit (alt_result[9], alt_result[30], alt_result[51], 4);
b64_from_24bit (alt_result[31], alt_result[52], alt_result[10], 4);
b64_from_24bit (alt_result[53], alt_result[11], alt_result[32], 4);
b64_from_24bit (alt_result[12], alt_result[33], alt_result[54], 4);
b64_from_24bit (alt_result[34], alt_result[55], alt_result[13], 4);
b64_from_24bit (alt_result[56], alt_result[14], alt_result[35], 4);
b64_from_24bit (alt_result[15], alt_result[36], alt_result[57], 4);
b64_from_24bit (alt_result[37], alt_result[58], alt_result[16], 4);
b64_from_24bit (alt_result[59], alt_result[17], alt_result[38], 4);
b64_from_24bit (alt_result[18], alt_result[39], alt_result[60], 4);
b64_from_24bit (alt_result[40], alt_result[61], alt_result[19], 4);
b64_from_24bit (alt_result[62], alt_result[20], alt_result[41], 4);
b64_from_24bit (0, 0, alt_result[63], 2);
if (buflen <= 0)
{
errno = ERANGE;
buffer = NULL;
}
else
*cp = '\0'; /* Terminate the string. */
/* Clear the buffer for the intermediate result so that people
attaching to processes or reading core dumps cannot get any
information. We do it in this way to clear correct_words[]
inside the SHA512 implementation as well. */
sha512_init_ctx (&ctx);
sha512_finish_ctx (&ctx, alt_result);
memset (temp_result, '\0', sizeof (temp_result));
memset (p_bytes, '\0', key_len);
memset (s_bytes, '\0', salt_len);
memset (&ctx, '\0', sizeof (ctx));
memset (&alt_ctx, '\0', sizeof (alt_ctx));
if (copied_key != NULL)
memset (copied_key, '\0', key_len);
if (copied_salt != NULL)
memset (copied_salt, '\0', salt_len);
return buffer;
}
/* This entry point is equivalent to the `crypt' function in Unix
libcs. */
char *
sha512_crypt (const char *key, const char *salt)
{
/* We don't want to have an arbitrary limit in the size of the
password. We can compute an upper bound for the size of the
result in advance and so we can prepare the buffer we pass to
`sha512_crypt_r'. */
static char *buffer = NULL;
static int buflen = 0;
int needed = (sizeof (sha512_salt_prefix) - 1
+ sizeof (sha512_rounds_prefix) + 9 + 1
+ strlen (salt) + 1 + 86 + 1);
if (buflen < needed)
{
char *new_buffer = (char *) realloc (buffer, needed);
if (new_buffer == NULL)
return NULL;
buffer = new_buffer;
buflen = needed;
}
return sha512_crypt_r (key, salt, buffer, buflen);
}

View file

@ -0,0 +1,6 @@
#ifndef SHA512CRYPT_H
#define SHA512CRYPT_H
char * sha512_crypt (const char *key, const char *salt);
#endif

View file

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

View file

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

View file

@ -0,0 +1,89 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="NetworkConnection" inherits="Reference" category="Core" version="3.1.2">
<brief_description>
</brief_description>
<description>
</description>
<tutorials>
</tutorials>
<methods>
<method name="define_checksum_msg_xml">
<return type="void">
</return>
<argument index="0" name="checksum_msg_xml" type="Array">
</argument>
<description>
</description>
</method>
<method name="define_lang">
<return type="void">
</return>
<argument index="0" name="lang" type="String">
</argument>
<description>
</description>
</method>
<method name="define_server">
<return type="void">
</return>
<argument index="0" name="host" type="String">
</argument>
<argument index="1" name="port" type="int">
</argument>
<description>
</description>
</method>
<method name="define_user">
<return type="void">
</return>
<argument index="0" name="user_addr" type="String">
</argument>
<argument index="1" name="user_key" type="String">
</argument>
<argument index="2" name="user_id" type="String">
</argument>
<description>
</description>
</method>
<method name="disconnect_server">
<return type="void">
</return>
<description>
</description>
</method>
<method name="get_state">
<return type="int">
</return>
<description>
</description>
</method>
<method name="process">
<return type="void">
</return>
<argument index="0" name="delta" type="int">
</argument>
<description>
</description>
</method>
<method name="send_system_disconnect">
<return type="void">
</return>
<description>
</description>
</method>
<method name="send_system_login">
<return type="void">
</return>
<description>
</description>
</method>
<method name="send_system_quit">
<return type="void">
</return>
<description>
</description>
</method>
</methods>
<constants>
</constants>
</class>

View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="NetworkConnectionCore" inherits="Reference" category="Core" version="3.1.2">
<brief_description>
</brief_description>
<description>
</description>
<tutorials>
</tutorials>
<methods>
</methods>
<constants>
</constants>
</class>

View file

@ -0,0 +1,105 @@
/*
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 "network_connection.h"
#include "network_connection_core.h"
void NetworkConnection::_bind_methods()
{
ClassDB::bind_method(D_METHOD("define_checksum_msg_xml", "checksum_msg_xml"), &NetworkConnection::define_checksum_msg_xml);
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("get_master_message_description_node"), &NetworkConnection::get_master_message_description_node);
}
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_server(String host, int64_t port)
{
NetworkConnectionCore::get_singleton()->define_server(host, port);
}
void NetworkConnection::define_user(String user_addr, String user_key, String user_id)
{
NetworkConnectionCore::get_singleton()->define_user(user_addr, user_key, user_id);
}
void NetworkConnection::define_lang(String lang)
{
NetworkConnectionCore::get_singleton()->define_lang(lang);
}
void NetworkConnection::send_system_login()
{
NetworkConnectionCore::get_singleton()->send_system_login();
}
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);
}
/*
MessageDescriptionNode & NetworkConnection::get_master_message_description_node()
{
return NetworkConnectionCore::get_singleton()->get_master_message_description_node();
}
*/
void terminate_network_connection()
{
NetworkConnectionCore::get_singleton()->terminate_connexion();
}

View file

@ -0,0 +1,55 @@
/*
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 "modules/bitstream/bitstream.h"
#include "modules/bitstreamqueue/bitstreamqueue.h"
#include "network_connection_core.h"
class NetworkConnection : public Reference {
GDCLASS(NetworkConnection, Reference)
protected:
static void _bind_methods();
public:
NetworkConnection();
~NetworkConnection();
/* _init must exist as it is called by Godot */
void _init() {};
void define_checksum_msg_xml(Array checksum_msg_xml);
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 disconnect_server();
void process(int delta);
int get_state();
//MessageDescriptionNode & get_master_message_description_node();
};
void terminate_network_connection();
#endif // NETWORK_CONNECTION_H

View file

@ -0,0 +1,564 @@
/*
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/>.
*/
#include "network_connection_core.h"
NetworkConnectionCore *NetworkConnectionCore::singleton = nullptr;
NetworkConnectionCore *NetworkConnectionCore::get_singleton()
{
if ( NetworkConnectionCore::singleton == nullptr )
NetworkConnectionCore::singleton = new NetworkConnectionCore();
return NetworkConnectionCore::singleton;
}
NetworkConnectionCore::NetworkConnectionCore()
{
this->_socketUDP = nullptr;
this->_state = STATE::NotInitialised;
}
NetworkConnectionCore::~NetworkConnectionCore()
{
NetworkConnectionCore::singleton = nullptr;
this->_state = STATE::NotInitialised;
}
int NetworkConnectionCore::get_state()
{
return this->_state;
}
void NetworkConnectionCore::autodefine_socket_udp()
{
// Create socket udp if not defined (If you don't use define_socket_udp)
if ( this->_socketUDP == nullptr)
{
this->_socketUDP = new PacketPeerUDP();
if ( this->_socketUDP == nullptr)
{
ERR_PRINT("Failed to open network");
throw "Failed to open network";
}
}
}
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_server(String host, int64_t port)
{
this->_host = host;
this->_port = 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;
}
void NetworkConnectionCore::define_lang(String lang)
{
this->_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;
}
/*
* Login
*/
void NetworkConnectionCore::send_system_login()
{
// 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();
}
/*
* Quit
*/
void NetworkConnectionCore::send_system_quit()
{
// TODO - check why we send quit_id
if ( this->_state != STATE::Connected && this->_state != STATE::ForceSynchronize )
return;
OS::get_singleton()->print("[%s:%d] send quit to server\n", __FILE__, __LINE__);
BitStream msgout;
msgout.put_uint32(this->_current_received_number);
msgout.put_bool(true);
msgout.put_uint8(CLFECOMMON::SYSTEM_QUIT_CODE);
msgout.put_sint32(this->_quit_id);
if ( this->_socketUDP->put_packet_buffer(msgout.get_data()) != Error::OK )
{
ERR_PRINT("Error to send disconnect");
}
this->_state = STATE::Quit;
}
/*
* Quit
*/
void NetworkConnectionCore::send_system_disconnect()
{
if ( this->_state != STATE::Connected && this->_state != STATE::ForceSynchronize )
return;
OS::get_singleton()->print("[%s:%d] send disconnect to server\n", __FILE__, __LINE__);
BitStream msgout;
msgout.put_uint32(this->_current_received_number);
msgout.put_bool(true);
msgout.put_uint8(CLFECOMMON::SYSTEM_DISCONNECTION_CODE);
if ( this->_socketUDP->put_packet_buffer(msgout.get_data()) != Error::OK )
{
ERR_PRINT("Error to send disconnect");
}
this->_socketUDP->close();
this->_state = STATE::Disconnect;
}
/*
*
*/
void NetworkConnectionCore::disconnect_server()
{
if (this->_state != STATE::Connected && this->_state != STATE::ForceSynchronize)
return;
send_system_disconnect();
}
/*
* Synchronize
*/
void NetworkConnectionCore::send_system_ack_sync()
{
// khanat-opennel-code/code/ryzom/server/src/frontend_service/fe_receive_sub.cpp:1121 void CFeReceiveSub::handleReceivedMsg( CClientHost *clienthost )
OS::get_singleton()->print("[%s:%d] Send system ACK sync\n", __FILE__, __LINE__);
if (this->_state != STATE::Connected && this->_state != STATE::Synchronize)
return;
OS::get_singleton()->print("[%s:%d] Send system ACK probe\n", __FILE__, __LINE__);
OS::get_singleton()->print("[%s:%d] send system ACK Sync to server\n", __FILE__, __LINE__);
Ref<BitStream> msgout;
msgout.instance();
msgout->put_uint32(this->_current_received_number);
msgout->put_bool(true);
msgout->put_uint8(CLFECOMMON::SYSTEM_ACK_SYNC_CODE);
msgout->put_sint32(this->_last_received_number);
msgout->put_sint32(this->_last_ack_in_long_ack);
this->_long_ack_bit_field.write_serial(msgout);
msgout->put_sint32(this->_latest_sync);
if (this->_socketUDP->put_packet_buffer(msgout->get_data()) != Error::OK)
{
ERR_PRINT("Error to send disconnect");
return;
}
msgout.unref();
this->_state = STATE::Connected;
}
void NetworkConnectionCore::receive_system_sync(Ref<BitStream> msgin)
{
int i;
bool valide = true;
//DEBUG_PRINT("SYSTEM_SYNC_CODE");
uint32_t synchronize = msgin->get_uint32();
int64_t stime = msgin->get_sint64();
uint32_t latestsync = msgin->get_uint32();
PoolByteArray msg_xml = msgin->get_array_uint8(16);
PoolByteArray database_xml = msgin->get_array_uint8(16);
OS::get_singleton()->print("[%s:%d] SYSTEM_SYNC_CODE synchronize:%u, stime:%ld, latestsync:%u\n", __FILE__, __LINE__, synchronize, stime, latestsync);
if ( msg_xml.size() != this->_checksum_msg_xml.size() )
{
valide = false;
ERR_PRINTS("MSG XML is incorrect (server:" + itos(msg_xml.size()) +", client:" + itos(this->_checksum_msg_xml.size()) + ")");
}
else
{
for(i=0; i<msg_xml.size(); ++i)
{
if ( (int) msg_xml[i] != (int) this->_checksum_msg_xml[i] )
{
valide = false;
ERR_PRINTS("MSG XML is incorrect (pos:" + itos(i) +")");
}
}
}
if ( valide == true )
{
OS::get_singleton()->print("MSG XML is correct\n");
this->_latest_sync = latestsync;
this->_synchronize = synchronize;
this->_current_server_tick = this->_synchronize + this->_current_received_number + 2;
this->_current_client_tick = this->_current_server_tick + (LCT + this->_ms_per_tick) / this->_ms_per_tick;
this->_current_client_time = this->_update_time - (LCT + this->_ms_per_tick);
this->_state = STATE::Synchronize;
}
else
ERR_PRINTS("MSG.XML is wrong");
}
/*
* Probe
*/
void NetworkConnectionCore::receive_system_probe(Ref<BitStream> msgin)
{
OS::get_singleton()->print("[%s:%d] SYSTEM_PROBE_CODE size:%d\n", __FILE__, __LINE__, this->_latest_probes.size());
this->_latest_probes.append(msgin->get_sint32());
}
void NetworkConnectionCore::send_system_ack_probe()
{
OS::get_singleton()->print("[%s:%d] Send system ACK probe\n", __FILE__, __LINE__);
// khanat-opennel-code/code/ryzom/server/src/frontend_service/fe_receive_sub.cpp:1121 void CFeReceiveSub::handleReceivedMsg( CClientHost *clienthost )
if (this->_state != STATE::Connected && this->_state != STATE::ForceSynchronize)
return;
OS::get_singleton()->print("[%s:%d] Send system ACK probe\n", __FILE__, __LINE__);
int max = this->_latest_probes.size();
if (max == 0 )
return;
if (this->_state == STATE::ForceSynchronize && max < 5)
return;
OS::get_singleton()->print("[%s:%d] send system ACK PROBE to server\n", __FILE__, __LINE__);
BitStream msgout;
msgout.put_uint32(this->_current_received_number);
msgout.put_bool(true);
msgout.put_uint8(CLFECOMMON::SYSTEM_ACK_PROBE_CODE);
msgout.put_sint32(max);
for(int i=0; i < max ; ++i )
{
int data = this->_latest_probes[i];
msgout.put_sint32(data);
}
if (this->_socketUDP->put_packet_buffer(msgout.get_data()) != Error::OK)
{
ERR_PRINT("Error to send disconnect");
return;
}
this->_latest_probes.clear();
if (this->_state == STATE::ForceSynchronize && max >= 5)
{
// We have send ACK, so now we clean all queue and received all message to synchronize
this->queue.clear();
this->_state = STATE::Connected;
}
}
/*
*
*/
void NetworkConnectionCore::wait_resynchronize(uint32_t current_received_number, Ref<BitStream> msgin)
{
bool system_mode;
this->_current_received_number = current_received_number;
system_mode = msgin->get_bool();
if ( system_mode == true )
{
int message = msgin->get_uint8();
switch (message)
{
case CLFECOMMON::SYSTEM_LOGIN_CODE:
OS::get_singleton()->print("SYSTEM_LOGIN_CODE\n");
break;
case CLFECOMMON::SYSTEM_SYNC_CODE:
OS::get_singleton()->print("SYSTEM_SYNC_CODE\n");
break;
case CLFECOMMON::SYSTEM_STALLED_CODE:
OS::get_singleton()->print("SYSTEM_STALLED_CODE\n");
break;
case CLFECOMMON::SYSTEM_SERVER_DOWN_CODE:
OS::get_singleton()->print("SYSTEM_SERVER_DOWN_CODE\n");
break;
case CLFECOMMON::SYSTEM_PROBE_CODE:
this->receive_system_probe(msgin);
break;
default:
ERR_PRINTS("Received unknown message [" + itos(message) + "]");
break;
}
}
this->_last_received_number = current_received_number;
}
/*
*
*/
void NetworkConnectionCore::decode_system_message(Ref<BitStream> msgin)
{
int message = msgin->get_uint8();
switch (message)
{
case CLFECOMMON::SYSTEM_LOGIN_CODE:
//DEBUG_PRINT("SYSTEM_LOGIN_CODE");
OS::get_singleton()->print("[%s:%d] SYSTEM_LOGIN_CODE\n", __FILE__, __LINE__);
break;
case CLFECOMMON::SYSTEM_SYNC_CODE:
this->receive_system_sync(msgin);
break;
case CLFECOMMON::SYSTEM_STALLED_CODE:
//DEBUG_PRINT("SYSTEM_STALLED_CODE");
OS::get_singleton()->print("[%s:%d] SYSTEM_STALLED_CODE\n", __FILE__, __LINE__);
break;
case CLFECOMMON::SYSTEM_SERVER_DOWN_CODE:
OS::get_singleton()->print("[%s:%d] SYSTEM_SERVER_DOWN_CODE\n", __FILE__, __LINE__);
break;
case CLFECOMMON::SYSTEM_PROBE_CODE:
this->receive_system_probe(msgin);
break;
default:
ERR_PRINTS("Received unknown message [" + itos(message) + "]");
break;
}
}
void NetworkConnectionCore::decode_normal_message(Ref<BitStream> msgin)
{
OS::get_singleton()->print("[%s:%d] Decode normal message\n", __FILE__, __LINE__);
}
/*
*
*/
void NetworkConnectionCore::analyze_message_received(uint32_t current_received_number, Ref<BitStream> msgin)
{
bool system_mode;
bool ackBool = false;
int ackBit = 0;
uint32_t i;
OS::get_singleton()->print("[%s:%d] analyze_message_received state:%d\n", __FILE__, __LINE__, this->_state);
this->_current_received_number = current_received_number;
system_mode = msgin->get_bool();
if ( system_mode == true )
{
OS::get_singleton()->print("Received system message\n");
if (this->_current_received_number == this->_last_received_number + 1)
{
OS::get_singleton()->print("Received message\n");
}
else if (this->_current_received_number < this->_last_received_number + 1)
{
OS::get_singleton()->print("Received old message\n");
return;
}
else if (this->_current_received_number > this->_last_received_number + 1)
{
OS::get_singleton()->print("Received message in future (lost some message)\n");
}
}
else
{
OS::get_singleton()->print("Received normal message\n");
}
if ( system_mode != true )
{
ackBool = true;
ackBit = 1;
}
if ( current_received_number - this->_last_received_number < 32 )
{
this->_ack_bit_mask <<= current_received_number - this->_last_received_number;
this->_ack_bit_mask |= this->_last_ack_bit << (current_received_number - this->_last_received_number - 1);
}
else if (((current_received_number - this->_last_received_number) == 32) && (this->_last_ack_bit != 0))
this->_ack_bit_mask = 0x80000000;
else
this->_ack_bit_mask = 0x00000000;
this->_last_ack_bit = ackBit;
for(i=this->_last_received_number + 1 ;i < _current_received_number; ++i)
this->_long_ack_bit_field.clear_bit(i & (NUM_BITS_IN_LONG_ACK -1) );
OS::get_singleton()->print("long_ack_bit_field.put : %u\n", current_received_number & (NUM_BITS_IN_LONG_ACK-1));
this->_long_ack_bit_field.put(current_received_number & (NUM_BITS_IN_LONG_ACK-1), ackBool);
// TODO - what's action when we have rotate onthis number (max -> 0)
if( this->_last_received_number > 0x08000000 )
{
if(this->_last_ack_in_long_ack <= (this->_last_received_number - NUM_BITS_IN_LONG_ACK))
this->_last_ack_in_long_ack = this->_last_received_number - NUM_BITS_IN_LONG_ACK + 1;
this->_last_received_number = current_received_number;
}
else
{
if(this->_last_ack_in_long_ack - 0x80000000 <= (this->_last_received_number - NUM_BITS_IN_LONG_ACK - 0x80000000))
this->_last_ack_in_long_ack = this->_last_received_number - NUM_BITS_IN_LONG_ACK + 1;
this->_last_received_number = current_received_number;
}
if ( system_mode == true )
this->decode_system_message(msgin);
else
this->decode_normal_message(msgin);
}
void NetworkConnectionCore::store_message_received(PoolByteArray & msgbytes)
{
int pos = this->queue.put_msgbytes(msgbytes);
Ref<BitStream> msgin = this->queue.get_msg(pos);
uint32_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
{
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);
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);
}
else // Received new message (but missing some message between) -> go to queue and cross finger to received the next message (for _last_received_number)
{
OS::get_singleton()->print("[%s:%d] current_received_number:%d / queue size:%d\n", __FILE__, __LINE__, current_received_number, this->queue.length());
if (this->queue.length() >= SIZE_QUEUE_MESSAGE)
{
ERR_PRINT("Network queue is full / wait re-synchronize");
this->_state = STATE::ForceSynchronize ;
return;
}
}
}
void NetworkConnectionCore::send_message()
{
if (this->_latest_probes.size() > 0)
send_system_ack_probe();
else if (this->_state == STATE::Synchronize)
send_system_ack_sync();
}
void NetworkConnectionCore::process(int delta)
{
if (this->_state == STATE::Disconnect || this->_state == STATE::NotInitialised)
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 ;
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);
}
send_message();
}
void NetworkConnectionCore::terminate_connexion()
{
if ( this->_socketUDP == nullptr )
return;
OS::get_singleton()->print("[%s:%d] Terminate network connexion\n", __FILE__, __LINE__);
delete this->_socketUDP;
this->_socketUDP = nullptr;
if ( NetworkConnectionCore::singleton != nullptr )
{
delete NetworkConnectionCore::singleton;
NetworkConnectionCore::singleton = nullptr;
}
}
/*
MessageDescriptionNode & NetworkConnectionCore::get_master_message_description_node()
{
return this->_message_description_node;
}
*/

View file

@ -0,0 +1,135 @@
/*
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 "core/reference.h"
#include "core/io/packet_peer_udp.h"
#include "modules/bitset/bitset.h"
#include "modules/bitstreamqueue/bitstreamqueue.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
class NetworkConnectionCore : public Reference {
GDCLASS(NetworkConnectionCore, Reference)
private:
static NetworkConnectionCore *singleton;
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;
int64_t _port;
String _host;
String _lang;
String _user_addr;
String _user_key;
String _user_id;
PacketPeerUDP * _socketUDP;
BitSet _long_ack_bit_field;
Array _latest_probes;
Array _checksum_msg_xml;
BitStreamQueue queue;
//MessageDescriptionNode _message_description_node;
public:
static NetworkConnectionCore * get_singleton();
NetworkConnectionCore();
~NetworkConnectionCore();
int get_state();
void autodefine_socket_udp();
void define_checksum_msg_xml(Array & checksum_msg_xml);
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 initialize();
void send_system_login();
void send_system_disconnect();
void send_system_quit();
void disconnect_server();
void send_system_ack_probe();
void receive_system_probe(Ref<BitStream> msgin);
void send_system_ack_sync();
void receive_system_sync(Ref<BitStream> msgin);
void decode_system_message(Ref<BitStream> msgin);
void decode_normal_message(Ref<BitStream> msgin);
void wait_resynchronize(uint32_t current_received_number, Ref<BitStream> msgin);
void analyze_message_received(uint32_t current_received_number, Ref<BitStream> msgin);
void store_message_received(PoolByteArray & msgbytes);
void send_message();
void process(int delta);
bool connected();
void terminate_connexion();
//MessageDescriptionNode & get_master_message_description_node();
};
#endif

View file

@ -0,0 +1,16 @@
/* register_types.cpp */
#include "register_types.h"
#include "core/class_db.h"
#include "network_connection.h"
#include "network_connection_core.h"
void register_networkconnection_types() {
ClassDB::register_class<NetworkConnection>();
ClassDB::register_class<NetworkConnectionCore>();
}
void unregister_networkconnection_types() {
// Nothing to do here in this example.
}

View file

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