update network part
This commit is contained in:
parent
67a9fa8dbc
commit
739d550043
8 changed files with 589 additions and 72 deletions
|
@ -23,11 +23,15 @@ func analyze_message(message):
|
|||
print(message['timestamp'])
|
||||
_string_manager.set_timestamp(message['timestamp'])
|
||||
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)
|
||||
var command = {'action': Action.ACTION_GENERIC_CODE, 'impulse': ImpulseBase.STRING_MANAGER_STRING_RQ, "stringId": message['dynId']}
|
||||
_networkconnection.put_command(command);
|
||||
_networkconnection.put_command(command);
|
||||
var i
|
||||
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);
|
||||
return
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
|
|
|
@ -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/server/src/entities_game_service/entity_manager/entity_callbacks.cpp void sendCharactersSummary( CPlayer *player, bool AllAutorized, uint32 bitfieldOwnerOfActiveAnimSession, uint32 bitfieldOwnerOfEditSession )
|
||||
uint32_t i;
|
||||
value["ServerPeopleActive"] = msgin->get_uint8();
|
||||
value["ServerCareerActive"] = msgin->get_uint8();
|
||||
value["server_people_active"] = msgin->get_uint8();
|
||||
value["server_career_active"] = msgin->get_uint8();
|
||||
uint32_t character_summaries_Len = msgin->get_uint32();
|
||||
|
||||
value["CharacterSummaries_Len"] = character_summaries_Len;
|
||||
value["character_summaries_len"] = character_summaries_Len;
|
||||
Array character_summaries;
|
||||
for(i=0;i<character_summaries_Len;++i)
|
||||
{
|
||||
Dictionary character;
|
||||
character["Version"] = msgin->get_version();
|
||||
character["Mainland"] = msgin->get_uint32();
|
||||
character["Name"] = msgin->get_ustring();
|
||||
character["People"] = msgin->get_uint32();
|
||||
character["Location"] = msgin->get_uint32();
|
||||
character["VisualPropA"] = msgin->get_uint64();
|
||||
character["VisualPropB"] = msgin->get_uint64();
|
||||
character["VisualPropC"] = msgin->get_uint64();
|
||||
character["SheetId"] = msgin->get_uint32();
|
||||
character["Title"] = msgin->get_sint32();
|
||||
character["CharacterSlot"] = msgin->get_uint8();
|
||||
character["InRingSession"] = msgin->get_bool();
|
||||
character["HasEditSession"] = msgin->get_bool();
|
||||
character["InNewbieland"] = msgin->get_bool();
|
||||
character["version"] = msgin->get_version();
|
||||
character["mainland"] = msgin->get_uint32();
|
||||
character["name"] = msgin->get_string_utf16(); // msgin->get_ustring();
|
||||
character["people"] = msgin->get_uint32();
|
||||
character["location"] = msgin->get_uint32();
|
||||
character["visual_prop_a"] = msgin->get_uint64();
|
||||
character["visual_prop_b"] = msgin->get_uint64();
|
||||
character["visual_prop_c"] = msgin->get_uint64();
|
||||
character["sheet_id"] = msgin->get_uint32();
|
||||
character["title"] = msgin->get_sint32();
|
||||
character["character_slot"] = msgin->get_uint8();
|
||||
character["in_ring_session"] = msgin->get_bool();
|
||||
character["has_edit_session"] = msgin->get_bool();
|
||||
character["in_newbieland"] = msgin->get_bool();
|
||||
character_summaries.append(character);
|
||||
}
|
||||
value["CharacterSummaries"] = character_summaries;
|
||||
value["character_summaries"] = character_summaries;
|
||||
|
||||
uint32_t shard_names_Len = msgin->get_uint32();
|
||||
value["shardNames_Len"] = shard_names_Len;
|
||||
value["shard_names_Len"] = shard_names_Len;
|
||||
Array shard_names;
|
||||
for(i=0;i<shard_names_Len;++i)
|
||||
{
|
||||
Dictionary shard_name;
|
||||
shard_name["ShardNames"] = msgin->get_string();
|
||||
shard_name["shard_names"] = msgin->get_string();
|
||||
shard_names.append(shard_name);
|
||||
}
|
||||
value["ShardNames"] = shard_names;
|
||||
value["shard_names"] = shard_names;
|
||||
|
||||
value["Privileges"] = msgin->get_string();
|
||||
value["FreeTrial"] = msgin->get_bool();
|
||||
value["privileges"] = msgin->get_string();
|
||||
value["free_trial"] = msgin->get_bool();
|
||||
|
||||
uint32_t mainlands_len = msgin->get_uint32();
|
||||
value["Mainlands_Len"] = mainlands_len;
|
||||
value["mainlands_len"] = mainlands_len;
|
||||
Array mainlands;
|
||||
for(i=0;i<mainlands_len;++i)
|
||||
{
|
||||
Dictionary mainland;
|
||||
mainland["id"] = msgin->get_uint32();
|
||||
mainland["Name"] = msgin->get_ustring();
|
||||
mainland["Description"] = msgin->get_ustring();
|
||||
mainland["LanguageCode"] = msgin->get_string();
|
||||
mainland["Online"] = msgin->get_bool();
|
||||
mainland["name"] = msgin->get_string_utf16(); // msgin->get_ustring();
|
||||
mainland["description"] = msgin->get_string_utf16(); // msgin->get_ustring();
|
||||
mainland["language_code"] = msgin->get_string();
|
||||
mainland["online"] = msgin->get_bool();
|
||||
mainlands.append(mainland);
|
||||
}
|
||||
value["Mainlands"] = mainlands;
|
||||
value["mainlands"] = mainlands;
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -999,17 +999,13 @@ void ActionFactory::decode_message(NetworkData * data, Ref<BitStream> msgin)
|
|||
}
|
||||
case ImpulseBase::Impulse::STRING_MANAGER_PHRASE_SEND:
|
||||
{
|
||||
int i = 1;
|
||||
uint32_t dynId = msgin->get_uint32();
|
||||
value["dynId"] = dynId;
|
||||
uint32_t StringId = msgin->get_uint32();
|
||||
value["StringId_0"] = StringId;
|
||||
uint32_t dyn_id = msgin->get_uint32();
|
||||
value["dyn_id"] = dyn_id;
|
||||
Array string_id;
|
||||
|
||||
while(msgin->number_bit_not_read() > 32)
|
||||
{
|
||||
StringId = msgin->get_uint32();
|
||||
value["StringId_" + itos(i)] = StringId;
|
||||
++i;
|
||||
}
|
||||
string_id.append(msgin->get_uint32());
|
||||
value["string_id"] = string_id;
|
||||
break;
|
||||
}
|
||||
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:
|
||||
{
|
||||
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;
|
||||
}
|
||||
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:
|
||||
{
|
||||
uint32_t stringId = value["stringId"];
|
||||
msgout->put_uint32(stringId);
|
||||
uint32_t string_id = value["string_id"];
|
||||
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());
|
||||
break;
|
||||
}
|
||||
|
@ -1595,8 +1672,7 @@ void ActionFactory::pack(NetworkData * data)
|
|||
last = size;
|
||||
msgout->put_uint32(size);
|
||||
msgout->get_array_uint8(size);
|
||||
//msgout->put_bitstream(msg.ptr());-------TODO
|
||||
data->_client_messages.append(msgout); // data->_client_messages.append(msgout->get_data());
|
||||
data->_client_messages.append(msgout);
|
||||
DBG_PRINT("[ActionFactory::pack] ACTION_GENERIC_MULTI_PART_CODE prepared :" + msgout->show_detail());
|
||||
msgout.unref();
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ Build :
|
|||
|
||||
#include "modules/bitstream/bitstream.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
|
||||
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_array_uint8", "value"), &BitStream::put_array_uint8);
|
||||
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_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_sint64"), &BitStream::get_sint64);
|
||||
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_bitstream", "length"), &BitStream::get_bitstream);
|
||||
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()
|
||||
|
@ -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 ret;
|
||||
|
@ -597,25 +619,42 @@ String BitStream::get_string()
|
|||
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;
|
||||
uint32_t size = this->get_uint32();
|
||||
union S {
|
||||
uint16_t v;
|
||||
char c[2];
|
||||
};
|
||||
|
||||
while(size > 0)
|
||||
uint32_t i = 0;
|
||||
uint8_t tmp[size];
|
||||
for(i=0;i<size;++i)
|
||||
{
|
||||
S x;
|
||||
x.v = this->get_uint16();
|
||||
CharString cs;
|
||||
cs += x.c[0];
|
||||
cs += x.c[1];
|
||||
ret += cs;
|
||||
--size;
|
||||
tmp[i] = this->get_uint16();
|
||||
}
|
||||
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;
|
||||
}
|
|
@ -63,6 +63,7 @@ public:
|
|||
void put_bitstream(BitStream & value);
|
||||
void put_bitstream(BitStream * value);
|
||||
void put_version(uint32_t value);
|
||||
void put_string_utf16(String value);
|
||||
|
||||
String show();
|
||||
String show_detail();
|
||||
|
@ -88,7 +89,8 @@ public:
|
|||
PoolByteArray get_array_uint8(uint32_t length);
|
||||
BitStream get_bitstream(uint32_t length);
|
||||
String get_string();
|
||||
String get_ustring();
|
||||
String get_string_utf16();
|
||||
String get_string_utf8();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
330
modules/bitstream/convert_utf16.cpp
Normal file
330
modules/bitstream/convert_utf16.cpp
Normal 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
|
||||
}
|
34
modules/bitstream/convert_utf16.h
Normal file
34
modules/bitstream/convert_utf16.h
Normal 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
|
|
@ -21,8 +21,8 @@
|
|||
#include "core/error_macros.h"
|
||||
#ifdef DEBUG_ENABLED
|
||||
#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
|
||||
#define DBG_PRINT(m_string)
|
||||
#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())
|
|
@ -397,26 +397,58 @@ void StateConnectionConnected::send_normal_message()
|
|||
DBG_PRINT("msgout C:" + msgout.show_detail());
|
||||
msgout.put_uint32(this->_data->_ack_bit_mask);
|
||||
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 )
|
||||
{
|
||||
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());
|
||||
msgout.put_uint8(1);
|
||||
DBG_PRINT("msgout F:" + msgout.show_detail());
|
||||
Ref<BitStream> tmp = this->_data->_client_messages.pop_front(); // PoolByteArray tmp = this->_data->_client_messages.pop_front();
|
||||
//msgout.put_array_uint8(tmp); // TODO - Erreur de copie (changer le type)
|
||||
msgout.put_bitstream(tmp.ptr()); /// ERREUR COPIE
|
||||
Ref<BitStream> tmp = this->_data->_client_messages.pop_front();
|
||||
msgout.put_bitstream(tmp.ptr());
|
||||
DBG_PRINT("Send message " + msgout.show_detail());
|
||||
if ( msgout.number_bit_not_read() > 3840 ) // 3840 = 480*8
|
||||
break;
|
||||
// break; // TODO - a supprimer pour l'instant on envoie qu'un paquet
|
||||
}
|
||||
*/
|
||||
DBG_PRINT("msgout G:" + msgout.show_detail());
|
||||
|
||||
DBG_PRINT("Send msg:" + itos(this->_data->_current_send_number) + " - " + msgout.show_detail());
|
||||
|
|
Loading…
Reference in a new issue