update network part

This commit is contained in:
AleaJactaEst 2020-05-04 18:23:44 +02:00
parent 67a9fa8dbc
commit 739d550043
8 changed files with 589 additions and 72 deletions

View file

@ -23,11 +23,15 @@ func analyze_message(message):
print(message['timestamp']) print(message['timestamp'])
_string_manager.set_timestamp(message['timestamp']) _string_manager.set_timestamp(message['timestamp'])
elif message['impulse'] == ImpulseBase.STRING_MANAGER_PHRASE_SEND: elif message['impulse'] == ImpulseBase.STRING_MANAGER_PHRASE_SEND:
if _string_manager.check_phases(message['dynId']) == false: if _string_manager.check_phases(message['dyn_id']) == false:
_phrases_not_decoded.append(message) _phrases_not_decoded.append(message)
var command = {'action': Action.ACTION_GENERIC_CODE, 'impulse': ImpulseBase.STRING_MANAGER_STRING_RQ, "stringId": message['dynId']} var i
_networkconnection.put_command(command); for i in range(0,message['string_id'].size()):
var id = message['string_id'][i]
print(id)
var command = {'action': Action.ACTION_GENERIC_CODE, 'impulse': ImpulseBase.STRING_MANAGER_STRING_RQ, "string_id": id}
_networkconnection.put_command(command); _networkconnection.put_command(command);
#_networkconnection.put_command(command);
return return
# Called every frame. 'delta' is the elapsed time since the previous frame. # Called every frame. 'delta' is the elapsed time since the previous frame.

View file

@ -75,61 +75,61 @@ void ActionFactory::decode_message(NetworkData * data, Ref<BitStream> msgin)
// khanat-opennel-code/code/ryzom/client/src/net_manager.cpp void impulseUserChars(NLMISC::CBitMemStream &impulse) // khanat-opennel-code/code/ryzom/client/src/net_manager.cpp void impulseUserChars(NLMISC::CBitMemStream &impulse)
// khanat-opennel-code/code/ryzom/server/src/entities_game_service/entity_manager/entity_callbacks.cpp void sendCharactersSummary( CPlayer *player, bool AllAutorized, uint32 bitfieldOwnerOfActiveAnimSession, uint32 bitfieldOwnerOfEditSession ) // khanat-opennel-code/code/ryzom/server/src/entities_game_service/entity_manager/entity_callbacks.cpp void sendCharactersSummary( CPlayer *player, bool AllAutorized, uint32 bitfieldOwnerOfActiveAnimSession, uint32 bitfieldOwnerOfEditSession )
uint32_t i; uint32_t i;
value["ServerPeopleActive"] = msgin->get_uint8(); value["server_people_active"] = msgin->get_uint8();
value["ServerCareerActive"] = msgin->get_uint8(); value["server_career_active"] = msgin->get_uint8();
uint32_t character_summaries_Len = msgin->get_uint32(); uint32_t character_summaries_Len = msgin->get_uint32();
value["CharacterSummaries_Len"] = character_summaries_Len; value["character_summaries_len"] = character_summaries_Len;
Array character_summaries; Array character_summaries;
for(i=0;i<character_summaries_Len;++i) for(i=0;i<character_summaries_Len;++i)
{ {
Dictionary character; Dictionary character;
character["Version"] = msgin->get_version(); character["version"] = msgin->get_version();
character["Mainland"] = msgin->get_uint32(); character["mainland"] = msgin->get_uint32();
character["Name"] = msgin->get_ustring(); character["name"] = msgin->get_string_utf16(); // msgin->get_ustring();
character["People"] = msgin->get_uint32(); character["people"] = msgin->get_uint32();
character["Location"] = msgin->get_uint32(); character["location"] = msgin->get_uint32();
character["VisualPropA"] = msgin->get_uint64(); character["visual_prop_a"] = msgin->get_uint64();
character["VisualPropB"] = msgin->get_uint64(); character["visual_prop_b"] = msgin->get_uint64();
character["VisualPropC"] = msgin->get_uint64(); character["visual_prop_c"] = msgin->get_uint64();
character["SheetId"] = msgin->get_uint32(); character["sheet_id"] = msgin->get_uint32();
character["Title"] = msgin->get_sint32(); character["title"] = msgin->get_sint32();
character["CharacterSlot"] = msgin->get_uint8(); character["character_slot"] = msgin->get_uint8();
character["InRingSession"] = msgin->get_bool(); character["in_ring_session"] = msgin->get_bool();
character["HasEditSession"] = msgin->get_bool(); character["has_edit_session"] = msgin->get_bool();
character["InNewbieland"] = msgin->get_bool(); character["in_newbieland"] = msgin->get_bool();
character_summaries.append(character); character_summaries.append(character);
} }
value["CharacterSummaries"] = character_summaries; value["character_summaries"] = character_summaries;
uint32_t shard_names_Len = msgin->get_uint32(); uint32_t shard_names_Len = msgin->get_uint32();
value["shardNames_Len"] = shard_names_Len; value["shard_names_Len"] = shard_names_Len;
Array shard_names; Array shard_names;
for(i=0;i<shard_names_Len;++i) for(i=0;i<shard_names_Len;++i)
{ {
Dictionary shard_name; Dictionary shard_name;
shard_name["ShardNames"] = msgin->get_string(); shard_name["shard_names"] = msgin->get_string();
shard_names.append(shard_name); shard_names.append(shard_name);
} }
value["ShardNames"] = shard_names; value["shard_names"] = shard_names;
value["Privileges"] = msgin->get_string(); value["privileges"] = msgin->get_string();
value["FreeTrial"] = msgin->get_bool(); value["free_trial"] = msgin->get_bool();
uint32_t mainlands_len = msgin->get_uint32(); uint32_t mainlands_len = msgin->get_uint32();
value["Mainlands_Len"] = mainlands_len; value["mainlands_len"] = mainlands_len;
Array mainlands; Array mainlands;
for(i=0;i<mainlands_len;++i) for(i=0;i<mainlands_len;++i)
{ {
Dictionary mainland; Dictionary mainland;
mainland["id"] = msgin->get_uint32(); mainland["id"] = msgin->get_uint32();
mainland["Name"] = msgin->get_ustring(); mainland["name"] = msgin->get_string_utf16(); // msgin->get_ustring();
mainland["Description"] = msgin->get_ustring(); mainland["description"] = msgin->get_string_utf16(); // msgin->get_ustring();
mainland["LanguageCode"] = msgin->get_string(); mainland["language_code"] = msgin->get_string();
mainland["Online"] = msgin->get_bool(); mainland["online"] = msgin->get_bool();
mainlands.append(mainland); mainlands.append(mainland);
} }
value["Mainlands"] = mainlands; value["mainlands"] = mainlands;
break; break;
} }
@ -999,17 +999,13 @@ void ActionFactory::decode_message(NetworkData * data, Ref<BitStream> msgin)
} }
case ImpulseBase::Impulse::STRING_MANAGER_PHRASE_SEND: case ImpulseBase::Impulse::STRING_MANAGER_PHRASE_SEND:
{ {
int i = 1; uint32_t dyn_id = msgin->get_uint32();
uint32_t dynId = msgin->get_uint32(); value["dyn_id"] = dyn_id;
value["dynId"] = dynId; Array string_id;
uint32_t StringId = msgin->get_uint32();
value["StringId_0"] = StringId;
while(msgin->number_bit_not_read() > 32) while(msgin->number_bit_not_read() > 32)
{ string_id.append(msgin->get_uint32());
StringId = msgin->get_uint32(); value["string_id"] = string_id;
value["StringId_" + itos(i)] = StringId;
++i;
}
break; break;
} }
case ImpulseBase::Impulse::STRING_MANAGER_STRING_RQ: case ImpulseBase::Impulse::STRING_MANAGER_STRING_RQ:
@ -1018,6 +1014,14 @@ void ActionFactory::decode_message(NetworkData * data, Ref<BitStream> msgin)
} }
case ImpulseBase::Impulse::STRING_MANAGER_STRING_RESP: case ImpulseBase::Impulse::STRING_MANAGER_STRING_RESP:
{ {
uint32_t string_id = msgin->get_uint32();
String str_utf8 = msgin->get_string_utf8();
DBG_PRINT("Decode message:" + ImpulseBase::get_command_name(id) + " string_id:" + itos(string_id) + " str_utf8:" + str_utf8);
//param.push_back(timestamp);
value["string_id"] = string_id;
value["str_utf8"] = str_utf8;
break; break;
} }
case ImpulseBase::Impulse::STRING_MANAGER_RELOAD_CACHE: case ImpulseBase::Impulse::STRING_MANAGER_RELOAD_CACHE:
@ -1503,8 +1507,81 @@ void ActionFactory::encode_message(Dictionary value, Ref<BitStream> msgout)
} }
case ImpulseBase::Impulse::STRING_MANAGER_STRING_RQ: case ImpulseBase::Impulse::STRING_MANAGER_STRING_RQ:
{ {
uint32_t stringId = value["stringId"]; uint32_t string_id = value["string_id"];
msgout->put_uint32(stringId); msgout->put_uint32(string_id);
DBG_PRINT("[ActionFactory::pack] ACTION_GENERIC_CODE encode_message B:" + itos(id) + " / " + msgout->show_detail());
break;
}
case ImpulseBase::Impulse::CONNECTION_CREATE_CHAR:
{
uint8_t slot = value["slot"];
uint8_t people = value["people"];
uint8_t sex = value["sex"];
uint8_t nb_point_fighter = value["nb_point_fighter"];
uint8_t nb_point_caster = value["nb_point_caster"];
uint8_t nb_point_crafter = value["nb_point_crafter"];
uint8_t nb_point_harvester = value["nb_point_harvester"];
uint8_t start_point = value["start_point"];
uint8_t hair_type = value["hair_type"];
uint8_t hair_color = value["hair_color"];
uint8_t gabarit_height = value["gabarit_height"];
uint8_t gabarit_torso_width = value["gabarit_torso_width"];
uint8_t gabarit_arms_width = value["gabarit_arms_width"];
uint8_t gabarit_legs_width = value["gabarit_legs_width"];
uint8_t gabarit_breast_size = value["gabarit_breast_size"];
uint8_t morph_target_1 = value["morph_target_1"];
uint8_t morph_target_2 = value["morph_target_2"];
uint8_t morph_target_3 = value["morph_target_3"];
uint8_t morph_target_4 = value["morph_target_4"];
uint8_t morph_target_5 = value["morph_target_5"];
uint8_t morph_target_6 = value["morph_target_6"];
uint8_t morph_target_7 = value["morph_target_7"];
uint8_t morph_target_8 = value["morph_target_8"];
uint8_t eyes_color = value["eyes_color"];
uint8_t tattoo = value["tattoo"];
uint8_t jacket_color = value["jacket_color"];
uint8_t trousers_color = value["trousers_color"];
uint8_t hat_color = value["hat_color"];
uint8_t arms_color = value["arms_color"];
uint8_t hands_color = value["hands_color"];
uint8_t feet_color = value["feet_color"];
uint32_t sheet_id = value["sheet_id"];
uint32_t session_id = value["session_id"];
String name = value["name"];
msgout->put_uint8(slot);
msgout->put_uint32(sheet_id);
msgout->put_uint32(session_id);
msgout->put_string_utf16(name);
msgout->put_uint8(people);
msgout->put_uint8(sex);
msgout->put_uint8(nb_point_fighter);
msgout->put_uint8(nb_point_caster);
msgout->put_uint8(nb_point_crafter);
msgout->put_uint8(nb_point_harvester);
msgout->put_uint8(start_point);
msgout->put_uint8(hair_type);
msgout->put_uint8(hair_color);
msgout->put_uint8(gabarit_height);
msgout->put_uint8(gabarit_torso_width);
msgout->put_uint8(gabarit_arms_width);
msgout->put_uint8(gabarit_legs_width);
msgout->put_uint8(gabarit_breast_size);
msgout->put_uint8(morph_target_1);
msgout->put_uint8(morph_target_2);
msgout->put_uint8(morph_target_3);
msgout->put_uint8(morph_target_4);
msgout->put_uint8(morph_target_5);
msgout->put_uint8(morph_target_6);
msgout->put_uint8(morph_target_7);
msgout->put_uint8(morph_target_8);
msgout->put_uint8(eyes_color);
msgout->put_uint8(tattoo);
msgout->put_uint8(jacket_color);
msgout->put_uint8(trousers_color);
msgout->put_uint8(hat_color);
msgout->put_uint8(arms_color);
msgout->put_uint8(hands_color);
msgout->put_uint8(feet_color);
DBG_PRINT("[ActionFactory::pack] ACTION_GENERIC_CODE encode_message B:" + itos(id) + " / " + msgout->show_detail()); DBG_PRINT("[ActionFactory::pack] ACTION_GENERIC_CODE encode_message B:" + itos(id) + " / " + msgout->show_detail());
break; break;
} }
@ -1595,8 +1672,7 @@ void ActionFactory::pack(NetworkData * data)
last = size; last = size;
msgout->put_uint32(size); msgout->put_uint32(size);
msgout->get_array_uint8(size); msgout->get_array_uint8(size);
//msgout->put_bitstream(msg.ptr());-------TODO data->_client_messages.append(msgout);
data->_client_messages.append(msgout); // data->_client_messages.append(msgout->get_data());
DBG_PRINT("[ActionFactory::pack] ACTION_GENERIC_MULTI_PART_CODE prepared :" + msgout->show_detail()); DBG_PRINT("[ActionFactory::pack] ACTION_GENERIC_MULTI_PART_CODE prepared :" + msgout->show_detail());
msgout.unref(); msgout.unref();
} }

View file

@ -22,6 +22,7 @@ Build :
#include "modules/bitstream/bitstream.h" #include "modules/bitstream/bitstream.h"
#include "modules/debug/debug.h" #include "modules/debug/debug.h"
#include "modules/bitstream/convert_utf16.h"
// TODO - check if on godot we have a function or variable to get if processor is little_endian or not // TODO - check if on godot we have a function or variable to get if processor is little_endian or not
bool little_endian = false; bool little_endian = false;
@ -52,6 +53,7 @@ void BitStream::_bind_methods()
ClassDB::bind_method(D_METHOD("put_string_hexa32", "hexa"), &BitStream::put_string_hexa32); 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("put_array_uint8", "value"), &BitStream::put_array_uint8);
ClassDB::bind_method(D_METHOD("put_version", "value"), &BitStream::put_version); ClassDB::bind_method(D_METHOD("put_version", "value"), &BitStream::put_version);
ClassDB::bind_method(D_METHOD("put_string_utf16", "value"), &BitStream::put_string_utf16);
ClassDB::bind_method(D_METHOD("show"), &BitStream::show); ClassDB::bind_method(D_METHOD("show"), &BitStream::show);
ClassDB::bind_method(D_METHOD("show_detail"), &BitStream::show_detail); ClassDB::bind_method(D_METHOD("show_detail"), &BitStream::show_detail);
@ -70,10 +72,12 @@ void BitStream::_bind_methods()
ClassDB::bind_method(D_METHOD("get_uint32"), &BitStream::get_uint32); 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_sint64"), &BitStream::get_sint64);
ClassDB::bind_method(D_METHOD("get_uint64"), &BitStream::get_uint64); ClassDB::bind_method(D_METHOD("get_uint64"), &BitStream::get_uint64);
ClassDB::bind_method(D_METHOD("get_version", "value"), &BitStream::get_version); ClassDB::bind_method(D_METHOD("get_version"), &BitStream::get_version);
ClassDB::bind_method(D_METHOD("get_array_uint8", "length"), &BitStream::get_array_uint8); ClassDB::bind_method(D_METHOD("get_array_uint8", "length"), &BitStream::get_array_uint8);
//ClassDB::bind_method(D_METHOD("get_bitstream", "length"), &BitStream::get_bitstream);
ClassDB::bind_method(D_METHOD("get_string"), &BitStream::get_string); ClassDB::bind_method(D_METHOD("get_string"), &BitStream::get_string);
ClassDB::bind_method(D_METHOD("get_ustring"), &BitStream::get_ustring); ClassDB::bind_method(D_METHOD("get_string_utf16"), &BitStream::get_string_utf16);
ClassDB::bind_method(D_METHOD("get_string_utf8"), &BitStream::get_string_utf8);
} }
void BitStream::clear() void BitStream::clear()
@ -321,6 +325,24 @@ void BitStream::put_version(uint32_t value)
} }
} }
void BitStream::put_string_utf16(String value)
{
uint16_t * u16_buf = NULL;
size_t u16_len = 0;
convert_utf8_to_utf16(value, &u16_buf, &u16_len);
this->put_uint32(u16_len);
if ( u16_len == 0 )
return;
for(uint32_t i=0;i<u16_len;++i)
{
this->put_uint16(u16_buf[i]);
}
delete [] u16_buf;
}
String BitStream::show() String BitStream::show()
{ {
String ret; String ret;
@ -597,25 +619,42 @@ String BitStream::get_string()
return ret; return ret;
} }
String BitStream::get_ustring() String BitStream::get_string_utf16()
{ {
// Read Utf-16 // https://en.wikipedia.org/wiki/UTF-16
// https://gist.github.com/rsms/716794
String ret; String ret;
uint32_t size = this->get_uint32(); uint32_t size = this->get_uint32();
union S { uint32_t i = 0;
uint16_t v; uint8_t tmp[size];
char c[2]; for(i=0;i<size;++i)
};
while(size > 0)
{ {
S x; tmp[i] = this->get_uint16();
x.v = this->get_uint16();
CharString cs;
cs += x.c[0];
cs += x.c[1];
ret += cs;
--size;
} }
ret = convert_utf16_to_utf8(tmp, i);
return ret;
}
String BitStream::get_string_utf8()
{
// https://en.wikipedia.org/wiki/UTF-8
String ret;
uint32_t i;
uint32_t size = this->get_uint32();
char * src = new char[size+1];
union S {
uint8_t v;
char c;
};
src[size] = 0;
for(i=0;i<size;++i)
{
S x;
x.v = this->get_uint8();
src[i] = x.c;
}
ret = String::utf8(src);
delete [] src;
return ret; return ret;
} }

View file

@ -63,6 +63,7 @@ public:
void put_bitstream(BitStream & value); void put_bitstream(BitStream & value);
void put_bitstream(BitStream * value); void put_bitstream(BitStream * value);
void put_version(uint32_t value); void put_version(uint32_t value);
void put_string_utf16(String value);
String show(); String show();
String show_detail(); String show_detail();
@ -88,7 +89,8 @@ public:
PoolByteArray get_array_uint8(uint32_t length); PoolByteArray get_array_uint8(uint32_t length);
BitStream get_bitstream(uint32_t length); BitStream get_bitstream(uint32_t length);
String get_string(); String get_string();
String get_ustring(); String get_string_utf16();
String get_string_utf8();
}; };
#endif #endif

View file

@ -0,0 +1,330 @@
/*
* Convert a UTF-16 string to UTF-8, mapping indices to provide low-complexity
* range and index lookups.
*
* Copyright 2010 Rasmus Andersson. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#include "convert_utf16.h"
#include "core/array.h"
#include "core/variant.h"
#include "core/int_types.h"
// ----------------------------------------------------------------------------
// Macros extracted from icu/unicode/utf16.h
/**
* Is this code unit a lead surrogate (U+d800..U+dbff)?
* @param c 16-bit code unit
* @return TRUE or FALSE
* @stable ICU 2.4
*/
#define U16_IS_LEAD(c) (((c)&0xfffffc00)==0xd800)
/**
* Is this code unit a trail surrogate (U+dc00..U+dfff)?
* @param c 16-bit code unit
* @return TRUE or FALSE
* @stable ICU 2.4
*/
#define U16_IS_TRAIL(c) (((c)&0xfffffc00)==0xdc00)
/**
* Helper constant for U16_GET_SUPPLEMENTARY. (0x35fdc00)
* @internal
*/
#define U16_SURROGATE_OFFSET ((0xd800<<10UL)+0xdc00-0x10000)
/**
* Get a supplementary code point value (U+10000..U+10ffff)
* from its lead and trail surrogates.
* The result is undefined if the input values are not
* lead and trail surrogates.
*
* @param lead lead surrogate (U+d800..U+dbff)
* @param trail trail surrogate (U+dc00..U+dfff)
* @return supplementary code point (U+10000..U+10ffff)
* @stable ICU 2.4
*/
#define U16_GET_SUPPLEMENTARY(lead, trail) \
(((uint32_t)(lead)<<10UL)+(uint32_t)(trail)-U16_SURROGATE_OFFSET)
/**
* Get a code point from a string at a code point boundary offset,
* and advance the offset to the next code point boundary.
* (Post-incrementing forward iteration.)
* "Unsafe" macro, assumes well-formed UTF-16.
*
* The offset may point to the lead surrogate unit
* for a supplementary code point, in which case the macro will read
* the following trail surrogate as well.
* If the offset points to a trail surrogate, then that itself
* will be returned as the code point.
* The result is undefined if the offset points to a single, unpaired lead surrogate.
*
* @param s const UChar * string
* @param i string offset
* @param c output uint32_t variable
* @see U16_NEXT
* @stable ICU 2.4
*/
#define U16_NEXT_UNSAFE(s, i, c) { \
(c)=(s)[(i)++]; \
if(U16_IS_LEAD(c)) { \
(c)=U16_GET_SUPPLEMENTARY((c), (s)[(i)++]); \
} \
}
/**
* Get a code point from a string at a code point boundary offset,
* and advance the offset to the next code point boundary.
* (Post-incrementing forward iteration.)
* "Safe" macro, handles unpaired surrogates and checks for string boundaries.
*
* The offset may point to the lead surrogate unit
* for a supplementary code point, in which case the macro will read
* the following trail surrogate as well.
* If the offset points to a trail surrogate or
* to a single, unpaired lead surrogate, then that itself
* will be returned as the code point.
*
* @param s const UChar * string
* @param i string offset, must be i<length
* @param length string length
* @param c output UChar32 variable
* @see U16_NEXT_UNSAFE
* @stable ICU 2.4
*/
#define U16_NEXT(s, i, length, c) { \
(c)=(s)[(i)++]; \
if(U16_IS_LEAD(c)) { \
uint16_t __c2; \
if((i)<(length) && U16_IS_TRAIL(__c2=(s)[(i)])) { \
++(i); \
(c)=U16_GET_SUPPLEMENTARY((c), __c2); \
} \
} \
}
// end of icu/unicode/utf16.h
// ----------------------------------------------------------------------------
// convert_utf16_to_utf8 based on HUTF8MappedUTF16String.mm
String convert_utf16_to_utf8(uint8_t * u16_buf, size_t u16_len)
{
String out;
int u8_len = 0;
size_t * u8to16_table = new size_t[u16_len*4];
char *u8buf = new char[u16_len*4+1];
// For each UTF-16 character...
for (size_t u16i=0; u16i < u16_len; )
{
// Retrieve 1-2 UTF-16 characters, forming one 32-bit unicode character
uint32_t u32c = 0;
size_t u16i_next = u16i;
// slower, but "safer"
// U16_NEXT(u16_buf_, u16i_next, u16_len_, u32c);
// faster, but does not handle unpaired surrogates or checks bounds
U16_NEXT_UNSAFE(u16_buf, u16i_next, u32c);
// u16 offset added to |u8to16_table|
size_t u16ix = u16i;
// Append u32c to u8buf (1-4 bytes)
if ((uint32_t)u32c <= 0x7f)
{
u8to16_table[u8_len] = u16ix;
u8buf[u8_len++] = (uint8_t)u32c;
{
CharString c;
c += u8buf[u8_len - 1];
}
} else {
if ((uint32_t)u32c <= 0x7ff)
{
u8to16_table[u8_len] = u16ix;
u8buf[u8_len++] = (uint8_t)((u32c>>6)|0xc0);
} else {
if ((uint32_t)u32c <= 0xffff)
{
u8to16_table[u8_len] = u16ix;
u8buf[u8_len++] = (uint8_t)((u32c>>12)|0xe0);
} else {
u8to16_table[u8_len] = u16ix;
u8buf[u8_len++] = (uint8_t)((u32c>>18)|0xf0);
u8to16_table[u8_len] = u16ix;
u8buf[u8_len++] = (uint8_t)(((u32c>>12)&0x3f)|0x80);
}
u8to16_table[u8_len] = u16ix;
u8buf[u8_len++] = (uint8_t)(((u32c>>6)&0x3f)|0x80);
}
u8to16_table[u8_len] = u16ix;
u8buf[u8_len++] = (uint8_t)((u32c&0x3f)|0x80);
}
u16i = u16i_next;
}
delete [] u8to16_table;
u8buf[u8_len++] = 0;
out = String::utf8(u8buf);
delete [] u8buf;
return out;
}
void convert_utf8_to_utf16(String input, uint16_t ** u16_buf, size_t * u16_len)
{
Array unicode;
CharString utf8 = input.utf8();
int i = 0;
#ifdef DEBUG_ENABLED
if ( u16_len == NULL )
{
ERR_PRINT("Bad ptr for u16_len");
throw "Bad ptr for u16_len";
}
if ( u16_buf == NULL )
{
ERR_PRINT("Bad ptr for u16_buf");
throw "Bad ptr for u16_buf";
}
if ( *u16_buf != NULL )
{
ERR_PRINT("Bad ptr u16_buf not empty");
throw "Bad ptr u16_buf not empty";
}
#endif
while (i < utf8.size())
{
uint32_t uni;
size_t todo;
//bool error = false;
unsigned char ch = (unsigned char) utf8[i++];
if (ch <= 0x7F)
{
uni = ch;
todo = 0;
}
else if (ch <= 0xBF)
{
ERR_PRINT("not a UTF-8 string");
*u16_len = 0;
return;
}
else if (ch <= 0xDF)
{
uni = ch&0x1F;
todo = 1;
}
else if (ch <= 0xEF)
{
uni = ch&0x0F;
todo = 2;
}
else if (ch <= 0xF7)
{
uni = ch&0x07;
todo = 3;
}
else
{
ERR_PRINT("not a UTF-8 string");
*u16_len = 0;
return;
}
for (size_t j = 0; j < todo; ++j)
{
if (i == utf8.size())
{
ERR_PRINT("not a UTF-8 string");
*u16_len = 0;
return;
}
ch = (unsigned char) utf8[i++];
if (ch < 0x80 || ch > 0xBF)
{
ERR_PRINT("not a UTF-8 string");
*u16_len = 0;
return;
}
uni <<= 6;
uni += ch & 0x3F;
}
if (uni >= 0xD800 && uni <= 0xDFFF)
{
ERR_PRINT("not a UTF-8 string");
*u16_len = 0;
return;
}
if (uni > 0x10FFFF)
{
ERR_PRINT("not a UTF-8 string");
*u16_len = 0;
return;
}
Variant data_pushed(uni);
unicode.push_back(data_pushed);
}
*u16_len = 0;
for (i = 0; i < unicode.size(); ++i)
{
unsigned long uni = unicode[i];
if (uni <= 0xFFFF)
{
(*u16_len) ++;
}
else
{
(*u16_len) ++;
(*u16_len) ++;
}
}
*u16_buf = new uint16_t[*u16_len];
size_t ii;
for (i = 0; i < unicode.size(); ++i)
{
unsigned long uni = unicode[i];
if (uni <= 0xFFFF)
{
(*u16_buf)[ii++] = uni;
}
else
{
uni -= 0x10000;
(*u16_buf)[ii++] = (uint16_t)((uni >> 10) + 0xD800);
(*u16_buf)[ii++] = (uint16_t)((uni & 0x3FF) + 0xDC00);
}
}
#ifdef DEBUG_ENABLED
if(ii > *u16_len)
{
ERR_PRINT("Out of array (max:" + itos(*u16_len) + " / current:" + itos(ii) + ")");
throw "Out of array";
}
#endif
}

View file

@ -0,0 +1,34 @@
/*
* Convert a UTF-16 string to UTF-8, mapping indices to provide low-complexity
* range and index lookups.
*
* Copyright 2010 Rasmus Andersson. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#ifndef CONVERT_UTF16_H
#define CONVERT_UTF16_H
#include "core/ustring.h"
String convert_utf16_to_utf8(uint8_t * u16_buf, size_t u16_len);
void convert_utf8_to_utf16(String input, uint16_t ** u16_buf, size_t * u16_len);
#endif // CONVERT_UTF16_H

View file

@ -21,8 +21,8 @@
#include "core/error_macros.h" #include "core/error_macros.h"
#ifdef DEBUG_ENABLED #ifdef DEBUG_ENABLED
#include "core/os/os.h" #include "core/os/os.h"
#define DBG_PRINT(m_string) OS::get_singleton()->print((String("DEBUG [") + String(__FILE__) + String(":") + String(uitos(__LINE__)) + String("] ") + String(m_string) + String("\n")).utf8()) #define DBG_PRINT(m_string) OS::get_singleton()->print("%s", (String("DEBUG [") + String(__FILE__) + String(":") + String(uitos(__LINE__)) + String("] ") + String(m_string) + String("\n")).utf8().ptr())
#else #else
#define DBG_PRINT(m_string) #define DBG_PRINT(m_string)
#endif #endif
#define INF_PRINT(m_string) OS::get_singleton()->print((String("INFO [") + String(__FILE__) + String(":") + String(uitos(__LINE__)) + String("] ") + String(m_string) + String("\n")).utf8()) #define INF_PRINT(m_string) OS::get_singleton()->print("%s", (String("INFO [") + String(__FILE__) + String(":") + String(uitos(__LINE__)) + String("] ") + String(m_string) + String("\n")).utf8().ptr())

View file

@ -397,26 +397,58 @@ void StateConnectionConnected::send_normal_message()
DBG_PRINT("msgout C:" + msgout.show_detail()); DBG_PRINT("msgout C:" + msgout.show_detail());
msgout.put_uint32(this->_data->_ack_bit_mask); msgout.put_uint32(this->_data->_ack_bit_mask);
DBG_PRINT("msgout D:" + msgout.show_detail()); DBG_PRINT("msgout D:" + msgout.show_detail());
// Method count element and send group
{
uint32_t nb = msgout.size_data() + 32 + 8;
uint8_t ele = 0;
while( (ele < this->_data->_client_messages.size()) && (ele < 255) )
{
Ref<BitStream> tmp = this->_data->_client_messages[ele];
++ ele;
nb += tmp->size_data();
if ( nb > 3840 ) // 3840 = 480*8
break;
}
if (ele > 0)
{
DBG_PRINT("Send message");
msgout.put_uint32(this->_data->_current_server_tick); // Cycle
DBG_PRINT("msgout E:" + msgout.show_detail());
msgout.put_uint8(ele);
DBG_PRINT("msgout F:" + msgout.show_detail());
while( ele > 0 )
{
Ref<BitStream> tmp = this->_data->_client_messages.pop_front();
msgout.put_bitstream(tmp.ptr());
DBG_PRINT("Send message " + msgout.show_detail());
-- ele;
if ( msgout.number_bit_not_read() > 3840 ) // 3840 = 480*8
break;
}
#ifdef DEBUG_ENABLED
if ( msgout.size_data() != nb ) // 3840 = 480*8
{
ERR_PRINT("****** " + itos(msgout.size_data()) + " / " + itos(nb));
}
#endif
}
}
// Method check size and send one element
/* /*
msgout.pushUint32(self.Cycle) // cycle = self._CurrentServerTick
numberActions = len(self.Actions)
msgout.pushUint8(numberActions)
*/
while( this->_data->_client_messages.size() > 0 ) while( this->_data->_client_messages.size() > 0 )
{ {
DBG_PRINT("Send message"); DBG_PRINT("Send message");
msgout.put_uint32(this->_data->_current_server_tick); msgout.put_uint32(this->_data->_current_server_tick); // Cycle
DBG_PRINT("msgout E:" + msgout.show_detail()); DBG_PRINT("msgout E:" + msgout.show_detail());
msgout.put_uint8(1); msgout.put_uint8(1);
DBG_PRINT("msgout F:" + msgout.show_detail()); DBG_PRINT("msgout F:" + msgout.show_detail());
Ref<BitStream> tmp = this->_data->_client_messages.pop_front(); // PoolByteArray tmp = this->_data->_client_messages.pop_front(); Ref<BitStream> tmp = this->_data->_client_messages.pop_front();
//msgout.put_array_uint8(tmp); // TODO - Erreur de copie (changer le type) msgout.put_bitstream(tmp.ptr());
msgout.put_bitstream(tmp.ptr()); /// ERREUR COPIE
DBG_PRINT("Send message " + msgout.show_detail()); DBG_PRINT("Send message " + msgout.show_detail());
if ( msgout.number_bit_not_read() > 3840 ) // 3840 = 480*8 if ( msgout.number_bit_not_read() > 3840 ) // 3840 = 480*8
break; break;
// break; // TODO - a supprimer pour l'instant on envoie qu'un paquet
} }
*/
DBG_PRINT("msgout G:" + msgout.show_detail()); DBG_PRINT("msgout G:" + msgout.show_detail());
DBG_PRINT("Send msg:" + itos(this->_data->_current_send_number) + " - " + msgout.show_detail()); DBG_PRINT("Send msg:" + itos(this->_data->_current_send_number) + " - " + msgout.show_detail());