2019-05-19 13:23:03 +00:00
#!/usr/bin/python3
# -*- coding: utf-8 -*-
#
# script to emulate client khanat
#
# 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/>.
2019-05-30 17:22:22 +00:00
# Ex.: ./client.py --khanat-host 172.17.0.3 -d --size-buffer-file 10241024
2019-05-19 13:23:03 +00:00
# Modifier les droits pour les nouveaux joueurs (accès à tout)
# mysql -u root -e "use nel_ams_lib;UPDATE settings SET Value = 7 WHERE settings.Setting = 'Domain_Auto_Add';"
import argparse
import http . client
import crypt
import logging
2019-05-30 17:19:54 +00:00
import os
2019-05-19 13:23:03 +00:00
import os . path
import sys
import urllib . request
import urllib . parse
import tempfile
from enum import IntEnum
from ctypes import *
import re
import random
import lzma
import socket
import struct
2019-05-30 17:19:54 +00:00
import xml . etree . ElementTree as ET
2019-05-30 18:40:42 +00:00
import hashlib
2019-05-30 21:46:07 +00:00
import time
2019-05-31 23:45:35 +00:00
import signal
2019-05-19 13:23:03 +00:00
2019-05-31 17:25:04 +00:00
INVALID_SLOT = 0xff
2019-05-19 13:23:03 +00:00
class BitStream ( ) :
def __init__ ( self ) :
self . _pos = 0
self . _read = 0
self . _tampon = [ ]
2019-06-04 19:19:06 +00:00
self . _groupRead = [ ]
def __len__ ( self ) :
return ( self . _pos + 7 ) / / 8
2019-05-19 13:23:03 +00:00
2019-05-30 17:19:54 +00:00
def needRead ( self ) :
return self . _pos - self . _read
def sizeData ( self ) :
return self . _pos
def sizeRead ( self ) :
return self . _read
2019-06-04 19:19:06 +00:00
def getRead ( self ) :
return self . _read
def getPos ( self ) :
return self . _pos
def putRead ( self , value ) :
if value > self . _pos :
raise ValueError
self . _read = value
2019-05-19 13:23:03 +00:00
# ------------------------------------
def internalSerial ( self , value , nbits ) :
if nbits == 0 :
return
elif nbits > 32 :
raise " Out of range "
pos = self . _pos % 8
if pos == 0 :
self . _tampon . append ( 0 )
# print(">", pos, value)
value = c_uint32 ( value ) . value
if nbits != 32 :
mask = ( 1 << nbits ) - 1 ;
v = value & mask ;
else :
v = value ;
_FreeBits = 8 - ( self . _pos % 8 )
if nbits > _FreeBits :
#print(">A")
self . _tampon [ - 1 ] | = ( v >> ( nbits - _FreeBits ) )
self . _pos + = _FreeBits
self . internalSerial ( v , nbits - _FreeBits )
else :
#print(">B")
self . _tampon [ - 1 ] | = ( v << ( _FreeBits - nbits ) )
self . _pos + = nbits
def pushBool ( self , valeur ) :
if valeur :
v = 1
else :
v = 0
self . internalSerial ( v , 1 )
def pushUint32 ( self , valeur ) :
self . internalSerial ( valeur , 32 )
def pushSint32 ( self , valeur ) :
self . internalSerial ( valeur , 32 )
def pushUint16 ( self , valeur ) :
self . internalSerial ( valeur , 16 )
def pushSint16 ( self , valeur ) :
self . internalSerial ( valeur , 16 )
def pushUint8 ( self , valeur ) :
self . internalSerial ( valeur , 8 )
def pushSint8 ( self , valeur ) :
self . internalSerial ( valeur , 8 )
def pushUint64 ( self , valeur ) :
self . internalSerial ( valeur , 32 )
self . internalSerial ( valeur >> 32 , 32 )
def pushSint64 ( self , valeur ) :
self . internalSerial ( valeur , 32 )
self . internalSerial ( valeur >> 32 , 32 )
def pushFloat ( self , valeur ) :
v = c_float ( valeur ) . value
v1 = struct . pack ( ' f ' , v )
v2 = struct . unpack ( ' <i ' , v1 ) [ 0 ]
self . internalSerial ( v2 , 32 )
def pushDouble ( self , valeur ) :
v = c_double ( valeur ) . value
v1 = struct . pack ( ' d ' , v )
v2 = struct . unpack ( ' <Q ' , v1 ) [ 0 ]
#self.internalSerial(v2, 32)
self . internalSerial ( v2 , 32 )
self . internalSerial ( v2 >> 32 , 32 )
def pushChar ( self , valeur ) :
v = ord ( valeur )
self . internalSerial ( v , 8 )
def pushString ( self , valeur ) :
2019-05-30 17:19:54 +00:00
#size=len(valeur)
2019-05-19 13:23:03 +00:00
#self.internalSerial(size, 32)
self . pushUint32 ( len ( valeur ) )
for x in valeur :
self . pushChar ( x )
#y = ord(x)
#self.internalSerial(y, 8)
2019-06-06 20:21:35 +00:00
def pushArrayUint8 ( self , valeur ) :
2019-05-30 17:37:42 +00:00
' ex.: pushArrayChar([0,1,3,4]) '
for i in valeur :
2019-05-30 18:40:42 +00:00
self . pushUint8 ( i )
2019-05-19 13:23:03 +00:00
2019-06-04 19:19:06 +00:00
def pushBitStream ( self , source ) :
srcRead = source . getRead ( )
source . putRead ( 0 )
need = 8 - ( self . _pos % 8 )
if need != 8 :
self . internalSerial ( source . readSerial ( need ) , need )
while source . needRead ( ) > = 8 :
2019-06-05 21:10:20 +00:00
self . pushUint8 ( source . readSerial ( 8 , False ) )
2019-06-04 19:19:06 +00:00
need = source . needRead ( )
if need > 0 :
2019-06-05 21:10:20 +00:00
self . internalSerial ( source . readSerial ( need , False ) , need )
2019-06-04 19:19:06 +00:00
source . putRead ( srcRead )
2019-05-19 13:23:03 +00:00
# ------------------------------------
2019-06-05 21:10:20 +00:00
def readSerial ( self , nbits , name = " " , decode = True , typeName = ' ' , emulate = False ) :
2019-05-19 13:23:03 +00:00
if nbits == 0 :
return
elif nbits > 32 :
raise " Out of range "
if self . _read + nbits > self . _pos :
raise " Stream Overflow "
2019-06-05 21:10:20 +00:00
if decode and not emulate :
self . _groupRead . append ( ( self . _read , self . _read + nbits , name , typeName ) )
if emulate :
oldRead = self . _read
2019-05-19 13:23:03 +00:00
value = 0
pos = self . _read / / 8
_FreeBits = 8 - ( self . _read % 8 )
v = self . _tampon [ pos ] & ( ( 1 << _FreeBits ) - 1 )
if nbits > _FreeBits :
value | = ( v << ( nbits - _FreeBits ) )
self . _read + = _FreeBits
2019-06-05 21:10:20 +00:00
value | = self . readSerial ( nbits - _FreeBits , decode = False )
2019-05-19 13:23:03 +00:00
else :
value | = ( v >> ( _FreeBits - nbits ) )
self . _read + = nbits
2019-06-05 21:10:20 +00:00
if emulate :
self . _read = oldRead
2019-05-19 13:23:03 +00:00
return value
2019-06-05 21:10:20 +00:00
def readBool ( self , name ) :
v = self . readSerial ( 1 , name = name , typeName = ' Bool ' )
2019-05-19 13:23:03 +00:00
if v != 0 :
return True
else :
return False
2019-06-05 21:10:20 +00:00
def readUint32 ( self , name , decode = True , typeName = ' Uint32 ' ) :
v = self . readSerial ( 32 , name = name , decode = decode , typeName = typeName )
2019-05-19 13:23:03 +00:00
return v
2019-06-12 21:14:56 +00:00
def readSint32 ( self , name , decode = True ) :
v = self . readSerial ( 32 , name = name , decode = decode , typeName = ' Sint32 ' )
2019-05-19 13:23:03 +00:00
return c_int32 ( v ) . value
2019-06-05 21:10:20 +00:00
def readUint16 ( self , name ) :
v = self . readSerial ( 16 , name = name , typeName = ' Uint16 ' )
2019-05-19 13:23:03 +00:00
return v
2019-06-05 21:10:20 +00:00
def readSint16 ( self , name ) :
v = self . readSerial ( 16 , name = name , typeName = ' Sint16 ' )
2019-05-19 13:23:03 +00:00
return c_int16 ( v ) . value
2019-06-05 21:10:20 +00:00
def readUint8 ( self , name , decode = True , typeName = ' Uint8 ' ) :
v = self . readSerial ( 8 , decode = decode , name = name , typeName = typeName )
2019-05-19 13:23:03 +00:00
return v
2019-06-05 21:10:20 +00:00
def readSint8 ( self , name ) :
v = self . readSerial ( 8 , name = name , typeName = ' Sint8 ' )
2019-05-19 13:23:03 +00:00
return c_int8 ( v ) . value
2019-06-05 21:10:20 +00:00
def readUint64 ( self , name ) :
self . _groupRead . append ( ( self . _read , self . _read + 64 , name , ' Uint64 ' ) )
v = self . readSerial ( 32 , decode = False )
v1 = self . readSerial ( 32 , decode = False )
2019-05-19 13:23:03 +00:00
v2 = v | ( v1 << 32 )
return v2
2019-06-05 21:10:20 +00:00
def readSint64 ( self , name ) :
self . _groupRead . append ( ( self . _read , self . _read + 64 , name , ' Sint64 ' ) )
v = self . readSerial ( 32 , decode = False )
v1 = self . readSerial ( 32 , decode = False )
2019-05-19 13:23:03 +00:00
v2 = v | ( v1 << 32 )
return c_int64 ( v2 ) . value
2019-06-05 21:10:20 +00:00
def readFloat ( self , name ) :
v = self . readSerial ( 32 , name = name , typeName = ' Float ' )
2019-05-19 13:23:03 +00:00
v1 = struct . pack ( ' I ' , v )
v2 = struct . unpack ( ' <f ' , v1 ) [ 0 ]
return v2
2019-06-05 21:10:20 +00:00
def readDouble ( self , name ) :
self . _groupRead . append ( ( self . _read , self . _read + 64 , name , ' Double ' ) )
v = self . readSerial ( 32 , decode = False )
2019-05-19 13:23:03 +00:00
v1 = struct . pack ( ' I ' , v )
2019-06-05 21:10:20 +00:00
w = self . readSerial ( 32 , decode = False )
2019-05-19 13:23:03 +00:00
w1 = struct . pack ( ' I ' , w )
x = v1 + w1
x1 = struct . unpack ( ' <d ' , x ) [ 0 ]
return x1
2019-06-05 21:10:20 +00:00
def readChar ( self , name , decode = True ) :
v = self . readUint8 ( name = name , decode = decode , typeName = ' Char ' )
2019-05-19 13:23:03 +00:00
return chr ( v )
2019-06-05 21:10:20 +00:00
def readString ( self , name ) :
2019-05-19 13:23:03 +00:00
tmp = ' '
2019-06-12 21:14:56 +00:00
_size = self . readUint32 ( name + ' :size ' , decode = True )
2019-06-05 21:10:20 +00:00
v1 = self . _read
2019-05-19 13:23:03 +00:00
while _size > 0 :
2019-06-05 21:10:20 +00:00
x = self . readChar ( ' ' , decode = False )
2019-05-19 13:23:03 +00:00
tmp + = x
_size - = 1
2019-06-05 21:10:20 +00:00
v2 = self . _read
if v2 > self . _pos :
raise ValueError
2019-06-12 21:14:56 +00:00
if v1 < v2 :
self . _groupRead . append ( ( v1 , v2 , name + ' :string ' , ' String ' ) )
2019-05-19 13:23:03 +00:00
return tmp
2019-06-02 13:45:55 +00:00
2019-06-05 21:10:20 +00:00
def readArrayUint8 ( self , size , name ) :
2019-05-30 17:19:54 +00:00
ret = [ ]
2019-06-05 21:10:20 +00:00
v1 = self . _read
2019-05-30 17:19:54 +00:00
for i in range ( 0 , size ) :
2019-06-05 21:10:20 +00:00
ret . append ( self . readUint8 ( ' ' , decode = False ) )
v2 = self . _read
self . _groupRead . append ( ( v1 , v2 , name , ' ArrayUint8 ' ) )
2019-05-30 17:19:54 +00:00
return ret
2019-05-19 13:23:03 +00:00
2019-06-05 21:10:20 +00:00
def readBitStreamUint8 ( self , size , name ) :
2019-06-02 13:45:55 +00:00
ret = BitStream ( )
2019-06-05 21:10:20 +00:00
v1 = self . _read
2019-06-02 13:45:55 +00:00
for i in range ( 0 , size ) :
2019-06-05 21:10:20 +00:00
ret . pushUint8 ( self . readUint8 ( ' ' , decode = False ) )
v2 = self . _read
self . _groupRead . append ( ( v1 , v2 , name , ' StreamUint8 ' ) )
2019-06-02 13:45:55 +00:00
return ret
2019-06-12 21:14:56 +00:00
def readCont ( self , name ) :
ret = BitStream ( )
size = self . readSint32 ( name = name + ' :len ' , decode = True )
v1 = self . _read
for i in range ( 0 , size ) :
ret . pushBool ( self . readSerial ( 1 , name = ' ' , decode = False ) )
v2 = self . _read
self . _groupRead . append ( ( v1 , v2 , name + ' :data ' , ' readCont ' ) )
return size , ret
2019-05-19 13:23:03 +00:00
# ------------------------------------
def __str__ ( self ) :
return ' ' . join ( [ chr ( x ) for x in self . _tampon ] )
def message ( self ) :
2019-06-04 19:19:06 +00:00
# return str(self._pos) + ':' + '.'.join([ format(x, "02x") for x in self._tampon])
return str ( self . _pos ) + ' : ' + ' . ' . join ( [ " {0:08b} " . format ( x ) for x in self . _tampon ] )
2019-05-19 13:23:03 +00:00
2019-05-19 14:10:18 +00:00
def toBytes ( self ) :
2019-05-19 13:23:03 +00:00
return bytes ( self . _tampon )
2019-05-19 14:10:18 +00:00
def fromBytes ( self , data ) :
self . _read = 0
self . _tampon = [ int ( x ) for x in data ]
self . _pos = len ( self . _tampon ) * 8
2019-05-30 17:19:54 +00:00
def showLastData ( self ) :
ret = " "
readBefore = self . _read
while self . _read < self . _pos :
if self . _pos - self . _read > = 8 :
2019-06-05 21:10:20 +00:00
nsize = 8
2019-05-30 17:19:54 +00:00
else :
2019-06-05 21:10:20 +00:00
nsize = self . _pos - self . _read
data = self . readSerial ( nsize , decode = False )
if nsize == 1 :
ret + = " {0:01b} " . format ( data )
elif nsize == 2 :
ret + = " {0:02b} " . format ( data )
elif nsize == 3 :
ret + = " {0:03b} " . format ( data )
elif nsize == 4 :
ret + = " {0:04b} " . format ( data )
elif nsize == 5 :
ret + = " {0:05b} " . format ( data )
elif nsize == 6 :
ret + = " {0:06b} " . format ( data )
elif nsize == 7 :
ret + = " {0:07b} " . format ( data )
else :
ret + = " {0:08b} " . format ( data )
2019-05-30 17:19:54 +00:00
if ret != " " :
ret + = " . "
2019-06-04 19:19:06 +00:00
ret + = " {0:08b} " . format ( data )
2019-05-30 17:19:54 +00:00
self . _read = readBefore
return ret
2019-06-02 13:45:55 +00:00
def showAllData ( self ) :
2019-06-04 19:19:06 +00:00
ret = " "
readBefore = self . _read
self . _read = 0
while self . _read < self . _pos :
if self . _pos - self . _read > = 8 :
2019-06-05 21:10:20 +00:00
nsize = 8
2019-06-04 19:19:06 +00:00
else :
2019-06-05 21:10:20 +00:00
nsize = self . _pos - self . _read
data = self . readSerial ( nsize , decode = False )
if nsize == 1 :
ret + = " {0:01b} " . format ( data )
elif nsize == 2 :
ret + = " {0:02b} " . format ( data )
elif nsize == 3 :
ret + = " {0:03b} " . format ( data )
elif nsize == 4 :
ret + = " {0:04b} " . format ( data )
elif nsize == 5 :
ret + = " {0:05b} " . format ( data )
elif nsize == 6 :
ret + = " {0:06b} " . format ( data )
elif nsize == 7 :
ret + = " {0:07b} " . format ( data )
else :
ret + = " {0:08b} " . format ( data )
2019-06-04 19:19:06 +00:00
self . _read = readBefore
ret2 = " "
last = 0
2019-06-05 21:10:20 +00:00
for x , y , name , typeName in self . _groupRead :
ret2 + = " [< " + str ( x ) + ' : ' + str ( y - 1 ) + " > " + str ( name ) + ' ( ' + typeName + ' ) = ' + ret [ x : y ] + " ] "
2019-06-04 19:19:06 +00:00
last = y
if last < self . _pos :
ret2 + = " { " + ret [ last : ] + " } "
return ret2
2019-06-05 21:10:20 +00:00
def showAllDataRaw ( self ) :
2019-06-02 13:45:55 +00:00
ret = " "
readBefore = self . _read
self . _read = 0
while self . _read < self . _pos :
if self . _pos - self . _read > = 8 :
2019-06-05 21:10:20 +00:00
nsize = 8
else :
nsize = self . _pos - self . _read
data = self . readSerial ( nsize , decode = False )
if nsize == 1 :
ret + = " {0:01b} " . format ( data )
elif nsize == 2 :
ret + = " {0:02b} " . format ( data )
elif nsize == 3 :
ret + = " {0:03b} " . format ( data )
elif nsize == 4 :
ret + = " {0:04b} " . format ( data )
elif nsize == 5 :
ret + = " {0:05b} " . format ( data )
elif nsize == 6 :
ret + = " {0:06b} " . format ( data )
elif nsize == 7 :
ret + = " {0:07b} " . format ( data )
2019-06-02 13:45:55 +00:00
else :
2019-06-05 21:10:20 +00:00
ret + = " {0:08b} " . format ( data )
2019-06-02 13:45:55 +00:00
if ret != " " :
ret + = " . "
self . _read = readBefore
return ret
2019-06-06 20:21:35 +00:00
def getPosInBit ( self ) :
return self . _pos
2019-05-31 17:25:04 +00:00
def TestBitStream ( ) :
2019-05-19 13:23:03 +00:00
a = BitStream ( )
a . pushBool ( True )
a . pushBool ( False )
a . pushBool ( True )
a . pushBool ( True )
a . pushUint32 ( 1234567890 )
a . pushSint32 ( - 1234567890 )
a . pushUint16 ( 12345 )
a . pushSint16 ( - 12345 )
a . pushUint8 ( 123 )
a . pushSint8 ( - 123 )
a . pushFloat ( - 3.3999999521443642e+38 ) #-3.4E+38) # 1.2339999675750732)
a . pushDouble ( - 1.7E+308 )
a . pushUint64 ( 16045690709418696365 )
a . pushSint64 ( - 1 )
a . pushChar ( ' a ' )
a . pushString ( " Test A Faire " )
2019-06-05 21:10:20 +00:00
print ( ' raw: ' )
print ( a . showAllDataRaw ( ) )
print ( " - " * 20 )
2019-05-19 14:10:18 +00:00
print ( " - " * 80 )
2019-06-05 21:10:20 +00:00
print ( a . readBool ( ' a1 ' ) )
print ( a . readBool ( ' a2 ' ) )
print ( a . readBool ( ' a3 ' ) )
print ( a . readBool ( ' a4 ' ) )
print ( a . readUint32 ( ' a5 ' ) )
print ( a . readSint32 ( ' a6 ' ) )
print ( a . readUint16 ( ' a7 ' ) )
print ( a . readSint16 ( ' a8 ' ) )
print ( a . readUint8 ( ' a9 ' ) )
print ( a . readSint8 ( ' a10 ' ) )
print ( a . readFloat ( ' a11 ' ) )
print ( a . readDouble ( ' a12 ' ) )
print ( a . readUint64 ( ' a13 ' ) )
print ( a . readSint64 ( ' a14 ' ) )
print ( a . readChar ( ' a15 ' ) )
print ( a . readString ( ' a16 ' ) )
2019-05-19 14:10:18 +00:00
print ( a . toBytes ( ) )
2019-06-05 21:10:20 +00:00
print ( " - " * 40 )
print ( a . showAllData ( ) )
2019-05-19 14:10:18 +00:00
print ( " - " * 80 )
b = BitStream ( )
b . fromBytes ( a . toBytes ( ) )
2019-06-05 21:10:20 +00:00
print ( b . readBool ( ' b1 ' ) )
print ( b . readBool ( ' b2 ' ) )
print ( b . readBool ( ' b3 ' ) )
print ( b . readBool ( ' b4 ' ) )
print ( b . readUint32 ( ' b5 ' ) )
print ( b . readSint32 ( ' b6 ' ) )
print ( b . readUint16 ( ' b7 ' ) )
print ( b . readSint16 ( ' b8 ' ) )
print ( b . readUint8 ( ' b9 ' ) )
print ( b . readSint8 ( ' b10 ' ) )
print ( b . readFloat ( ' b11 ' ) )
print ( b . readDouble ( ' b12 ' ) )
print ( b . readUint64 ( ' b13 ' ) )
print ( b . readSint64 ( ' b14 ' ) )
print ( b . readChar ( ' b15 ' ) )
print ( b . readString ( ' b16 ' ) )
2019-05-19 14:10:18 +00:00
print ( b . toBytes ( ) )
2019-06-05 21:10:20 +00:00
print ( " - " * 40 )
print ( b . showAllData ( ) )
2019-06-04 19:19:06 +00:00
print ( " - " * 80 )
c = BitStream ( )
c . pushBool ( True )
c . pushBitStream ( a )
c . pushBitStream ( b )
2019-06-05 21:10:20 +00:00
print ( c . readBool ( ' c1 ' ) )
2019-06-04 19:19:06 +00:00
print ( " - " * 80 )
2019-06-05 21:10:20 +00:00
print ( c . readBool ( ' c2 ' ) )
print ( c . readBool ( ' c3 ' ) )
print ( c . readBool ( ' c4 ' ) )
print ( c . readBool ( ' c5 ' ) )
print ( c . readUint32 ( ' c6 ' ) )
print ( c . readSint32 ( ' c7 ' ) )
print ( c . readUint16 ( ' c8 ' ) )
print ( c . readSint16 ( ' c9 ' ) )
print ( c . readUint8 ( ' c10 ' ) )
print ( c . readSint8 ( ' c11 ' ) )
print ( c . readFloat ( ' c12 ' ) )
print ( c . readDouble ( ' c13 ' ) )
print ( c . readUint64 ( ' c14 ' ) )
print ( c . readSint64 ( ' c15 ' ) )
print ( c . readChar ( ' c16 ' ) )
print ( c . readString ( ' c17 ' ) )
2019-06-04 19:19:06 +00:00
print ( c . toBytes ( ) )
2019-06-05 21:10:20 +00:00
print ( " - " * 50 )
print ( c . showAllData ( ) )
print ( " - " * 50 )
print ( c . readBool ( ' c18 ' ) )
print ( c . readBool ( ' c19 ' ) )
print ( c . readBool ( ' c20 ' ) )
print ( c . readBool ( ' c21 ' ) )
print ( c . readUint32 ( ' c22 ' ) )
print ( c . readSint32 ( ' c23 ' ) )
print ( c . readUint16 ( ' c24 ' ) )
print ( c . readSint16 ( ' c25 ' ) )
print ( c . readUint8 ( ' c26 ' ) )
print ( c . readSint8 ( ' c27 ' ) )
print ( c . readFloat ( ' c28 ' ) )
print ( c . readDouble ( ' c29 ' ) )
print ( c . readUint64 ( ' c30 ' ) )
print ( c . readSint64 ( ' c31 ' ) )
print ( c . readChar ( ' c32 ' ) )
print ( " - " * 40 )
print ( c . showAllData ( ) )
print ( c . readString ( ' c33 ' ) )
print ( " - " * 40 )
print ( c . showAllData ( ) )
2019-06-04 19:19:06 +00:00
print ( c . toBytes ( ) )
2019-06-05 21:10:20 +00:00
print ( " - " * 40 )
print ( c . showAllDataRaw ( ) )
print ( " - " * 20 )
print ( c . showAllData ( ) )
print ( " - " * 80 )
2019-06-04 19:19:06 +00:00
2019-05-31 17:25:04 +00:00
NL_BITLEN = 32
class CBitSet :
def __init__ ( self ) :
self . data = self . resize ( 1024 )
self . NumBits = 0
self . MaskLast = 0
def resize ( self , numBits ) :
self . data = [ 0 for _ in range ( 0 , ( numBits + NL_BITLEN - 1 ) / / NL_BITLEN ) ]
self . NumBits = numBits
nLastBits = self . NumBits & ( NL_BITLEN - 1 )
if nLastBits == 0 :
self . MaskLast = ~ 0
else :
self . MaskLast = ( 1 << nLastBits ) - 1
self . clearAll ( )
def clearData ( self ) :
self . data = [ ]
self . NumBits = 0
self . MaskLast = 0
def clearAll ( self ) :
for i in range ( 0 , len ( self . data ) ) :
self . data [ i ] = 0
def set ( self , bitNumber , value ) :
2019-06-12 21:14:56 +00:00
log = logging . getLogger ( ' myLogger ' )
log . debug ( " CBitSet::set %d %s " % ( bitNumber , str ( value ) ) )
2019-05-31 17:25:04 +00:00
mask = bitNumber & ( NL_BITLEN - 1 )
mask = 1 << mask
if value :
self . data [ bitNumber >> 5 ] | = mask
else :
self . data [ bitNumber >> 5 ] & = ~ mask
def get ( self , bitNumber ) :
mask = bitNumber & ( NL_BITLEN - 1 ) ;
mask = 1 << mask ;
return self . data [ bitNumber >> 5 ] & mask != 0
def setBit ( self , bitNumber ) :
self . set ( bitNumber , True )
def clearBit ( self , bitNumber ) :
self . set ( bitNumber , False )
def __str__ ( self ) :
return ' . ' . join ( [ hex ( x ) for x in self . data ] )
def writeSerial ( self , msgout ) :
# v = 0 # currentVersion
# if v >= 0xff:
# msgout.pushUint8(0xff)
# msgout.pushUint8(v)
# else:
# msgout.pushUint8(v)
2019-06-12 21:14:56 +00:00
log = logging . getLogger ( ' myLogger ' )
log . debug ( " CBitSet::writeSerial NumBits: %d len: %d " % ( self . NumBits , len ( self . data ) ) )
msgout . pushUint8 ( 0 ) # currentVersion = 0
2019-05-31 17:25:04 +00:00
msgout . pushUint32 ( self . NumBits )
msgout . pushUint32 ( len ( self . data ) ) # il est lié à 'self.NumBits' dommage que l'on envoie celui-la
for x in self . data :
msgout . pushUint32 ( x )
def TestCBitSet ( ) :
cBitSet = CBitSet ( )
cBitSet . resize ( 1024 )
cBitSet . set ( 1 , True )
cBitSet . set ( 3 , True )
cBitSet . set ( 2 , False )
cBitSet . set ( 13 , True )
cBitSet . set ( 128 , True )
cBitSet . set ( 1023 , True )
print ( cBitSet )
print ( cBitSet . get ( 3 ) )
cBitSet . set ( 3 , False )
print ( cBitSet )
print ( cBitSet . get ( 3 ) )
def getTextMD5 ( dataRawXml ) :
log = logging . getLogger ( ' myLogger ' )
dataNew = ' '
for data in dataRawXml :
if data != ' \r ' : # '\015' ignore caractère \r\n =>
dataNew + = data
else :
log . debug ( " ***** data: %d " % ( ord ( data ) ) )
m = hashlib . md5 ( )
m . update ( dataNew . encode ( ' utf-8 ' ) )
#print(m.hexdigest())
#print(m.digest())
return m . digest ( )
2019-05-19 13:23:03 +00:00
2019-05-30 17:19:54 +00:00
class CFileChild ( ) :
def __init__ ( self , name , pos , size ) :
self . name = name
self . pos = pos
self . size = size
def __str__ ( self ) :
return self . name + ' (pos: ' + str ( self . pos ) + ' , size: ' + str ( self . size ) + ' ) '
class CFileList ( ) :
def __init__ ( self , name , fullpath ) :
self . name = name
self . fullpath = fullpath
self . child = [ ]
def addchild ( self , name , pos , size ) :
child = CFileChild ( name , pos , size )
self . child . append ( child )
def __str__ ( self ) :
return self . name + ' [ ' + ' , ' . join ( [ str ( x ) for x in self . child ] ) + ' ] '
class CFileContainer ( ) :
def __init__ ( self ) :
self . log = logging . getLogger ( ' myLogger ' )
self . list = [ ]
def addSearchPath ( self , path ) :
if not path :
return
self . log . debug ( " read path: " + str ( path ) )
onlyfiles = [ f for f in os . listdir ( path ) if os . path . isfile ( os . path . join ( path , f ) ) ]
self . log . debug ( " read files: " + ' , ' . join ( onlyfiles ) )
for filename in onlyfiles :
extension = os . path . splitext ( filename ) [ 1 ]
if extension == ' .bnp ' :
# Container for multi file
fullpath = os . path . join ( path , filename )
size = os . path . getsize ( fullpath )
data = CFileList ( filename , fullpath )
with open ( fullpath , ' rb ' ) as fp :
fp . seek ( size - 4 )
nOffsetFromBeginning = int . from_bytes ( fp . read ( 4 ) , byteorder = ' little ' , signed = False )
self . log . debug ( " [ %s ] nOffsetFromBeginning: %u " % ( filename , nOffsetFromBeginning ) )
fp . seek ( nOffsetFromBeginning )
nNbFile = int . from_bytes ( fp . read ( 4 ) , byteorder = ' little ' , signed = False )
self . log . debug ( " [ %s ] nNbFile: %u " % ( filename , nNbFile ) )
for i in range ( 0 , nNbFile ) :
nStringSize = int . from_bytes ( fp . read ( 1 ) , byteorder = ' little ' , signed = False )
FileName = fp . read ( nStringSize ) . decode ( )
nFileSize2 = int . from_bytes ( fp . read ( 4 ) , byteorder = ' little ' , signed = False )
nFilePos = int . from_bytes ( fp . read ( 4 ) , byteorder = ' little ' , signed = False )
self . log . debug ( " [ %s ] ( %d ) sizestring: %d file: %s size2: %d pos: %d " % ( filename , i , nStringSize , FileName , nFileSize2 , nFilePos ) )
data . addchild ( FileName , nFilePos , nFileSize2 )
fp . close ( )
self . list . append ( data )
def search ( self , name ) :
for x in self . list :
for y in x . child :
if y . name == name :
self . log . debug ( " file: %s child: %s pos: %d size: %d " , x . name , y . name , y . pos , y . size )
return x . fullpath , y . pos , y . size
self . log . debug ( ' - ' * 80 )
return None , None , None
def getdata ( self , name ) :
fullpath , pos , size = self . search ( name )
self . log . debug ( " file: %s pos: %d size: %d " , fullpath , pos , size )
data = None
with open ( fullpath , ' rb ' ) as fp :
fp . seek ( pos )
data = fp . read ( size )
fp . close ( )
return data
2019-05-19 13:23:03 +00:00
class TConnectionState ( IntEnum ) :
NotInitialised = 0 # nothing happened yet
NotConnected = 1 # init() called
Authenticate = 2 # connect() called, identified by the login server
Login = 3 # connecting to the frontend, sending identification
Synchronize = 4 # connection accepted by the frontend, synchronizing
Connected = 5 # synchronized, connected, ready to work
Probe = 6 # connection lost by frontend, probing for response
Stalled = 7 # server is stalled
Disconnect = 8 # disconnect() called, or timeout, or connection closed by frontend
Quit = 9 # quit() called
2019-05-31 23:45:35 +00:00
2019-05-31 17:25:04 +00:00
class TActionCode ( IntEnum ) :
ACTION_POSITION_CODE = 0
ACTION_GENERIC_CODE = 1
ACTION_GENERIC_MULTI_PART_CODE = 2
ACTION_SINT64 = 3
ACTION_SYNC_CODE = 10
ACTION_DISCONNECTION_CODE = 11
ACTION_ASSOCIATION_CODE = 12
ACTION_LOGIN_CODE = 13
ACTION_TARGET_SLOT_CODE = 40
ACTION_DUMMY_CODE = 99
2019-05-31 23:45:35 +00:00
2019-05-31 17:25:04 +00:00
class CLFECOMMON ( IntEnum ) :
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
2019-05-19 13:23:03 +00:00
2019-05-31 23:45:35 +00:00
2019-05-19 13:23:03 +00:00
class Card ( IntEnum ) :
BEGIN_TOKEN = 0
END_TOKEN = 1
SINT_TOKEN = 2
UINT_TOKEN = 3
FLOAT_TOKEN = 4
STRING_TOKEN = 5
FLAG_TOKEN = 6
EXTEND_TOKEN = 7
class TType ( IntEnum ) :
STRUCT_BEGIN = 0
STRUCT_END = 1
FLAG = 2
SINT32 = 3
UINT32 = 4
FLOAT32 = 5
STRING = 6
SINT64 = 7
UINT64 = 8
FLOAT64 = 9
EXTEND_TYPE = 10
NB_TYPE = 11
class TExtendType :
ET_SHEET_ID = 0
ET_64_BIT_EXTENDED_TYPES = 0x80000000
ET_ENTITY_ID = 0x80000000 # ET_ENTITY_ID = ET_64_BIT_EXTENDED_TYPES
class CBNPFileVersion :
def __init__ ( self ) :
self . VersionNumber = None
self . FileTime = None
self . FileSize = None
self . v7ZFileSize = None
self . PatchSize = None
self . HashKey = [ ]
def __str__ ( self ) :
return " VersionNumber: " + str ( self . VersionNumber ) + " , FileTime: " + str ( self . FileTime ) + " , FileSize: " + str ( self . FileSize ) + " , 7ZFileSize: " + str ( self . v7ZFileSize ) + " , PatchSize: " + str ( self . PatchSize ) + " , HashKey: " + str ( self . HashKey )
class CBNPFile :
def __init__ ( self ) :
self . FileName = None
self . Versions = [ ]
self . IsIncremental = False
def __str__ ( self ) :
return str ( self . FileName ) + ' ( ' + ' , ' . join ( [ str ( x ) for x in self . Versions ] ) + ' ) '
def update ( self , FileName ) :
self . FileName = FileName
class CBNPCategorySet :
def __init__ ( self ) :
self . _Name = " "
self . _IsOptional = False
self . _UnpackTo = " "
self . _IsIncremental = False
self . _CatRequired = " "
self . _Hidden = False
2019-05-30 17:19:54 +00:00
self . _Files = [ ]
2019-05-19 13:23:03 +00:00
def __str__ ( self ) :
2019-05-30 17:19:54 +00:00
return self . _Name + ' (IsOptional: ' + str ( self . _IsOptional ) + ' , UnpackTo: ' + self . _UnpackTo + ' , IsIncremental: ' + str ( self . _IsIncremental ) + ' , CatRequired: ' + self . _CatRequired + ' , Hidden: ' + str ( self . _Hidden ) + ' , Files: ' + str ( self . _Files ) + ' ) '
2019-05-19 13:23:03 +00:00
# #####################################################
# persistent_data.h:140 # struct CArg
# #####################################################
class CArgV1 ( Structure ) :
_fields_ = [ ( " i32_1 " , c_uint ) ,
( " i32_2 " , c_uint ) ]
class CArgV2 ( Structure ) :
_fields_ = [ ( " ex32_1 " , c_uint ) ,
( " ex32_2 " , c_uint ) ]
class CArgV3 ( Union ) :
_fields_ = [ ( " ex32 " , CArgV2 ) ,
( " ExData32 " , c_uint ) ,
( " ExData64 " , c_ulong ) ]
class CArgV4 ( Structure ) :
_fields_ = [ ( " ExType " , c_uint ) ,
( " ex " , CArgV3 ) ]
class CArgV5 ( Union ) :
_fields_ = [ ( " i " , CArgV1 ) ,
( " ii32 " , c_int ) ,
( " ii64 " , c_long ) ,
( " i32 " , c_uint ) ,
( " i64 " , c_ulong ) ,
( " f32 " , c_float ) ,
( " f64 " , c_double ) ,
( " ex " , CArgV4 ) ]
class CArg :
2019-05-31 17:25:04 +00:00
# union
# {
# struct
# {
# uint32 i32_1;
# uint32 i32_2;
# } i;
#
# sint32 i32;
# sint64 i64;
# float f32;
# double f64;
#
# struct
# {
# uint32 ExType;
# union
# {
# struct
# {
# uint32 ex32_1;
# uint32 ex32_2;
# };
#
# uint32 ExData32;
# uint64 ExData64;
# } ex;
# } ex;
# } _Value;
2019-05-19 13:23:03 +00:00
def __init__ ( self ) :
self . _value = CArgV5 ( )
self . _value . ii64 = 0
self . _value . i64 = 0
self . _type = 0
self . _string = 0
self . _type64 = False
def read_Type ( self ) :
return self . _type
def write_Type ( self , value ) :
self . _type = value
def write_Type64 ( self , value ) :
self . _type64 = value
def read_String ( self ) :
return self . _string
def write_String ( self , value ) :
self . _string = value
def read_i32_1 ( self ) :
return self . _value . i . i32_1
def write_i32_1 ( self , value ) :
self . _value . i . i32_1 = value
def read_i32_2 ( self ) :
return self . _value . i . i32_2
def write_i32_2 ( self , value ) :
self . _value . i . i32_2 = value
def read_i32 ( self ) :
return self . _value . i32
def write_i32 ( self , value ) :
self . _value . i32 = value
def read_i64 ( self ) :
return self . _value . i64
def write_i64 ( self , value ) :
self . _value . i64 = value
def read_f32 ( self ) :
return self . _value . f32
def write_f32 ( self , value ) :
self . _value . f32 = value
def read_f64 ( self ) :
return self . _value . f64
def write_f64 ( self , value ) :
self . _value . f64 = value
def read_ExType ( self ) :
return self . _value . ex . ExType
def write_ExType ( self , value ) :
self . _value . ex . ExType = value
def read_ex32_1 ( self ) :
return self . _value . ex . ex . ex32 . ex32_1
def write_ex32_1 ( self , value ) :
self . _value . ex . ex . ex32 . ex32_1 = value
def read_ex32_2 ( self ) :
return self . _value . ex . ex . ex32 . ex32_2
def write_ex32_2 ( self , value ) :
self . _value . ex . ex . ex32 . ex32_2 = value
def read_ExData32 ( self ) :
return self . _value . ex . ex . ExData32
def write_ExData32 ( self , value ) :
self . _value . ex . ex . ExData32 = value
def read_ExData64 ( self ) :
return self . _value . ex . ex . ExData64
def write_ExData64 ( self , value ) :
self . _value . ex . ex . ExData64 = value
def isExtended ( self ) :
if self . _type == TType . EXTEND_TYPE :
return True
elif self . _type == TType . STRUCT_BEGIN :
self . log . error ( " Can ' t extract a value from a structure delimiter " )
sys . exit ( 2 )
elif self . _type == TType . STRUCT_END :
self . log . error ( " Can ' t extract a value from a structure delimiter " )
sys . exit ( 2 )
return False
def isFlag ( self ) :
if self . _type == TType . FLAG :
return True
else :
return False
def asUint ( self ) :
if self . _type == TType . STRUCT_BEGIN or self . _type == TType . STRUCT_END :
self . log . error ( " Can ' t extract a value from a structure delimiter " )
sys . exit ( 2 )
elif self . _type == TType . SINT32 :
return self . read_i32 ( )
elif self . _type == TType . UINT32 :
return self . read_i32 ( )
elif self . _type == TType . SINT64 :
return self . read_i64 ( )
elif self . _type == TType . UINT64 :
return self . read_i64 ( )
elif self . _type == TType . FLOAT32 :
return self . read_i32 ( )
elif self . _type == TType . FLOAT64 :
return self . read_i64 ( )
elif self . _type == TType . STRING :
return int ( self . _string )
elif self . _type == TType . FLAG :
return " 1 "
elif self . _type == TType . EXTEND_TYPE :
if self . read_ExType ( ) == TExtendType . ET_SHEET_ID :
return self . read_ExData32 ( )
elif self . read_ExType ( ) == TExtendType . ET_ENTITY_ID :
return self . read_ExData64 ( )
log = logging . getLogger ( ' myLogger ' )
log . error ( " This should never happen! " )
sys . exit ( 2 )
def __str__ ( self ) :
log = logging . getLogger ( ' myLogger ' )
log . debug ( self . _type )
if self . _type == TType . STRUCT_BEGIN or self . _type == TType . STRUCT_END :
return ' '
elif self . _type64 :
# To be confirm for extend
return str ( self . read_ExData64 ( ) )
elif self . _type == TType . SINT32 :
return str ( self . read_i32 ( ) )
elif self . _type == TType . UINT32 :
return str ( self . read_i32 ( ) )
elif self . _type == TType . SINT64 :
return str ( self . read_i64 ( ) )
elif self . _type == TType . UINT64 :
return str ( self . read_i64 ( ) )
elif self . _type == TType . FLOAT32 :
return str ( self . read_i32 ( ) )
elif self . _type == TType . FLOAT64 :
return str ( self . read_i64 ( ) )
elif self . _type == TType . STRING :
return self . _string
elif self . _type == TType . FLAG :
return " 1 "
return ' ? '
def asSint ( self ) :
self . log . error ( " TODO " )
sys . exit ( 2 )
def asFloat ( self ) :
self . log . error ( " TODO " )
sys . exit ( 2 )
def asDouble ( self ) :
self . log . error ( " TODO " )
sys . exit ( 2 )
def asString ( self ) :
if self . _type == TType . STRUCT_BEGIN or self . _type == TType . STRUCT_END :
self . log . error ( " Can ' t extract a value from a structure delimiter " )
sys . exit ( 2 )
elif self . _type == TType . SINT32 :
return str ( self . read_ii32 ( ) )
elif self . _type == TType . UINT32 :
return str ( self . read_i32 ( ) )
elif self . _type == TType . SINT64 :
return str ( self . read_ii64 ( ) )
elif self . _type == TType . UINT64 :
return str ( self . read_i64 ( ) )
elif self . _type == TType . FLOAT32 :
return str ( self . read_f32 ( ) )
elif self . _type == TType . FLOAT64 :
return str ( self . read_f64 ( ) )
elif self . _type == TType . STRING :
return self . _string
elif self . _type == TType . FLAG :
return " 1 "
elif self . _type == TType . EXTEND_TYPE :
self . log . error ( " TODO " )
sys . exit ( 2 )
# switch(_Value.ExType)
# {
# case ET_SHEET_ID:
# {
# NLMISC::CSheetId sheetId(_Value.ExData32);
# return sheetId.toString(true);
# }
# case ET_ENTITY_ID:
# {
# NLMISC::CEntityId entityId(_Value.ExData64);
# return entityId.toString();
# }
# default:
# break;
# }
self . log . error ( " This should never happen! " )
sys . exit ( 2 )
def asUCString ( self ) :
self . log . error ( " TODO " )
sys . exit ( 2 )
def asEntityId ( self ) :
self . log . error ( " TODO " )
sys . exit ( 2 )
def asSheetId ( self ) :
self . log . error ( " TODO " )
sys . exit ( 2 )
def typeName ( self ) :
self . log . error ( " TODO " )
sys . exit ( 2 )
# #####################################################
#
# #####################################################
2019-06-04 19:19:06 +00:00
class CGenericMultiPartTemp ( ) :
def __init__ ( self , log ) :
self . log = log
self . NbBlock = 0xFFFFFFFF
self . NbCurrentBlock = 0
self . TempSize = 0
self . Temp = [ ]
self . BlockReceived = [ ]
2019-06-12 21:14:56 +00:00
def set ( self , Number , Part , NbBlock , PartCont , decodeImpulse ) :
2019-06-04 19:19:06 +00:00
'''
khanat - opennel - code / code / ryzom / client / src / network_connection . cpp # void CNetworkConnection::CGenericMultiPartTemp::set (CActionGenericMultiPart *agmp, CNetworkConnection *parent)
'''
if self . NbBlock == 0xFFFFFFFF :
# Initialize
self . NbBlock = NbBlock
self . NbCurrentBlock = 0
self . TempSize = 0
self . Temp = [ ]
while len ( self . Temp ) < NbBlock :
self . Temp . append ( None )
while len ( self . BlockReceived ) < NbBlock :
self . BlockReceived . append ( False )
if self . BlockReceived [ Part ] :
self . log . warning ( ' This part is already received, discard it %d ' % Part )
return
self . Temp [ Part ] = PartCont
self . BlockReceived [ Part ] = True
self . NbCurrentBlock + = 1
self . TempSize + = len ( PartCont )
self . log . debug ( " NbCurrentBlock: %d / NbBlock: %d " % ( self . NbCurrentBlock , self . NbBlock ) )
if self . NbCurrentBlock == self . NbBlock :
# reform the total action
bms = BitStream ( )
self . NbBlock == 0xFFFFFFFF
for data in self . Temp :
bms . pushBitStream ( data )
2019-06-12 21:14:56 +00:00
self . log . debug ( " CGenericMultiPartTemp : data : %s " % bms . showAllData ( ) )
self . log . debug ( " TODO " )
decodeImpulse . execute ( bms )
else :
self . log . debug ( " CGenericMultiPartTemp : Wait other block " )
class ECharacterTitle ( IntEnum ) :
'''
khanat - opennel - code / code / ryzom / common / src / game_share / character_title . h # enum ECharacterTitle
'''
Refugee = 0
Homin = 1 #
Novice_Artisan = 2 #
Novice_Warrior = 3 #
Novice_Harvester = 4 #
Novice_Magician = 5 #
Artisan_Apprentice = 6 #
Magician_Apprentice = 7 #
Defensive_Magician = 8 #
Offensive_Magician = 9 #
Mentalist = 10 #
Summoner = 11 #
Master_Of_Illusion = 12 #
Mind_Lord = 13 #
Healer = 14 #
Priest = 15 #
Master_Of_Life = 16 #
Celestial_Guardian = 17 #
Disturber = 18 #
Affliction_Bringer = 19 #
Master_Of_Torment = 20 #
Avatar_Of_Sorrow = 21 #
Destroyer = 22 #
Archmage = 23 #
Master_Of_Pain = 24 #
Avatar_Of_Destruction = 25 #
Elementalist = 26 #
Alchemist = 27 #
Biomancer = 28 #
Master_Of_Energies = 29 #
Chosen_Of_Atys = 30 #
Warrior_Apprentice = 31 #
Melee_Warrior = 32 #
Range_Fighter = 33 #
Light_Armsman = 34 #
Heavy_Armsman = 35 #
Close_Fighter = 36 #
Gunman = 37 #
Heavy_Gunman = 38 #
Advanced_Gunman = 39 #
Advanced_Heavy_Gunman = 40 #
Bludgeoner = 41 #
Skewerer = 42 #
Slasher = 43 #
Smasher = 44 #
Impaler = 45 #
Cleaver = 46 #
Advanced_Close_Fighter = 47 #
Maceman = 48 #
Brute = 49 #
Spearman = 50 #
Axeman = 51 #
Swordsman = 52 #
Heavy_Maceman = 53 #
Pikeman = 54 #
Heavy_Axeman = 55 #
Heavy_Swordsman = 56 #
Knifeman = 57 #
Hand_To_Hand_Fighter = 58 #
Bowman = 59 #
Pistoleer = 60 #
Heavy_Bowman = 61 #
Artilleryman = 62 #
Rifleman = 63 #
Master_Maceman = 64 #
Master_Brute = 65 #
Master_Spearman = 66 #
Master_Axeman = 67 #
Master_Swordsman = 68 #
Master_Heavy_Maceman = 69 #
Master_Pikeman = 70 #
Master_Heavy_Axeman = 71 #
Master_Heavy_Swordsman = 72 #
Master_Knifeman = 73 #
Master_Hand_To_Hand_Fighter = 74 #
Master_Bowman = 75 #
Master_Pistoleer = 76 #
Master_Heavy_Bowman = 77 #
Master_Artilleryman = 78 #
Master_Rifleman = 79 #
Armorer_Apprentice = 80 #
Jeweler_Apprentice = 81 #
Melee_Weapon_Smith_Apprentice = 82 #
Range_Weapon_Smith_Apprentice = 83 #
Heavy_Armorer = 84 #
Light_Armorer = 85 #
Medium_Armorer = 86 #
Shield_Smith = 87 #
Jeweler = 88 #
Melee_Weapon_Smith = 89 #
Melee_Heavy_Weapon_Smith = 90 #
Melee_Light_Weapon_Smith = 91 #
Range_Weapon_Smith = 92 #
Range_Heavy_Weapon_Smith = 93 #
Advanced_Heavy_Armorer = 94 #
Advanced_Light_Armorer = 95 #
Advanced_Medium_Armorer = 96 #
Advanced_Shield_Smith = 97 #
Advanced_Jeweler = 98 #
Advanced_Melee_Weapon_Smith = 99 #
Advanced_Melee_Heavy_Weapon_Smith = 100 #
Advanced_Melee_Light_Weapon_Smith = 101 #
Advanced_Range_Weapon_Smith = 102 #
Advanced_Range_Heavy_Weapon_Smith = 103 #
Expert_Heavy_Armorer = 104 #
Expert_Light_Armorer = 105 #
Expert_Medium_Armorer = 106 #
Expert_Shield_Smith = 107 #
Expert_Jeweler = 108 #
Expert_Melee_Weapon_Smith = 109 #
Expert_Melee_Heavy_Weapon_Smith = 110 #
Expert_Melee_Light_Weapon_Smith = 111 #
Expert_Range_Weapon_Smith = 112 #
Expert_Range_Heavy_Weapon_Smith = 113 #
Heavy_Armorer_Master = 114 #
Light_Armorer_Master = 115 #
Medium_Armorer_Master = 116 #
Shield_Smith_Master = 117 #
Jeweler_Master = 118 #
Melee_Weapon_Smith_Master = 119 #
Melee_Heavy_Weapon_Smith_Master = 120 #
Melee_Light_Weapon_Smith_Master = 121 #
Range_Weapon_Smith_Master = 122 #
Range_Heavy_Weapon_Smith_Master = 123 #
Forager_Apprentice = 124 #
Forager = 125 #
Desert_Forager = 126 #
Forest_Forager = 127 #
Jungle_Forager = 128 #
Lacustre_Forager = 129 #
Prime_Roots_Forager = 130 #
Advanced_Desert_Forager = 131 #
Advanced_Forest_Forager = 132 #
Advanced_Jungle_Forager = 133 #
Advanced_Lacustre_Forager = 134 #
Advanced_Prime_Roots_Forager = 135 #
Expert_Desert_Forager = 136 #
Expert_Forest_Forager = 137 #
Expert_Jungle_Forager = 138 #
Expert_Lacustre_Forager = 139 #
Expert_Prime_Roots_Forager = 140 #
Master_Desert_Forager = 141 #
Master_Forest_Forager = 142 #
Master_Jungle_Forager = 143 #
Master_Lacustre_Forager = 144 #
Master_Prime_Roots_Forager = 145 #
Kami_Ally = 146 #
Karavan_Ally = 147 #
Title00000 = 148 #
Title00001 = 149 # // Journeyer
Title00002 = 150 # // Novice Kitin Hunter
Title00003 = 151 # // Kitin Hunter
Title00004 = 152 # // Master Kitin Hunter
Title00005 = 153 # // Kitin Eradicator
Title00006 = 154 # // Kitin Mass Murderer
Title00007 = 155 # // Matis Guardian
Title00008 = 156 # // Fyros Guardian
Title00009 = 157 # // Tryker Guardian
Title00010 = 158 # // Zorai Guardian
Title00011 = 159 # // Atys Guardian
Title00012 = 160 #
Title00013 = 161 #
Title00014 = 162 # // The fortunate
Title00015 = 163 # // Jinxed
Title00016 = 164 #
Title00017 = 165 #
Title00018 = 166 #
Title00019 = 167 #
Title00020 = 168 # // Fyros Patriot
Title00021 = 169 # // Matis Vassal
Title00022 = 170 # // Tryker Citizen
Title00023 = 171 # // Zorai Initiate
Title00024 = 172 # // Kami Disciple
Title00025 = 173 # // Karavan Follower
Title00026 = 174 # // Fyros Akenak
Title00027 = 175 # // Matis Noble
Title00028 = 176 # // Tryker Taliar
Title00029 = 177 # // Zorai Awakened
Title00030 = 178 # // Marauder
Title00031 = 179 # // Fyros Ambassador
Title00032 = 180 # // Matis Ambassador
Title00033 = 181 # // Tryker Ambassador
Title00034 = 182 # // Zorai Ambassador
Title00035 = 183 #
Title00036 = 184 #
Title00037 = 185 #
Title00038 = 186 #
Title00039 = 187 #
Title00040 = 188 #
Title00041 = 189 #
Title00042 = 190 #
Title00043 = 191 #
Title00044 = 192 #
Title00045 = 193 #
Title00046 = 194 #
Title00047 = 195 # // Machinegunner
Title00048 = 196 # // Assault Machinegunner
Title00049 = 197 #
Title00050 = 198 # // Apprentice Butcher
Title00051 = 199 # // Butcher
Title00052 = 200 # // Apprentice Florist
Title00053 = 201 # // Florist
Title00054 = 202 # // Apprentice Water-Carrier
Title00055 = 203 # // Water-Carrier
Title00056 = 204 # // Apprentice Magnetic
Title00057 = 205 # // Magnetic Cartographe
Title00058 = 206 # // Apprentice Toolmaker
Title00059 = 207 # // Toolmaker
Title00060 = 208 # // Apprentice Rescuer
Title00061 = 209 # // Rescuer
Title00062 = 210 # // Apprentice Larvester
Title00063 = 211 # // Larvester
Title00064 = 212 # // Apprentice Scrollmaker
Title00065 = 213 # // Scrollmaker
Title00066 = 214 #
Title00067 = 215 #
Title00068 = 216 #
Title00069 = 217 #
Title00070 = 218 #
Title00071 = 219 #
Title00072 = 220 #
Title00073 = 221 #
Title00074 = 222 #
Title00075 = 223 #
Title00076 = 224 #
Title00077 = 225 #
Title00078 = 226 #
Title00079 = 227 # // Wayfarer
WIND = Title00079 # // Title for player come from old Windermmer community
FBT = 228 #
BeginGmTitle = 229 #
# SGM = BeginGmTitle #
GM = 230 #
VG = 231 #
SG = 232 #
G = 233 #
CM = 234 #
EM = 235 #
EG = 236 #
OBSERVER = 237 #
# EndGmTitle = OBSERVER,
NB_CHARACTER_TITLE = 238
class SPropVisualA ( ) :
def __init__ ( self ) :
'''
khanat - opennel - code / code / ryzom / common / src / game_share / player_visual_properties . h # struct SPropVisualA
'''
self . Sex = False #: 1; // max: 2 current: 2
self . JacketModel = 0 #: 8; // max: 256 current: 93
self . JacketColor = 0 #: 3; // max: 8 current: 8
self . TrouserModel = 0 #: 8; // max: 256 current: 104
self . TrouserColor = 0 #: 3; // max: 8 current: 8
self . WeaponRightHand = 0 #: 10; // max: 1024 current: 457
self . WeaponLeftHand = 0 #: 8; // max: 256 current: 63
self . ArmModel = 0 #: 8; // max: 256 current: 94
self . ArmColor = 0 #: 3; // max: 8 current: 8
self . HatModel = 0 #: 9; // max: 512 current: 192
self . HatColor = 0 #: 3; // max: 8 current: 8
def read ( self , msgin ) :
self . Sex = msgin . readBool ( ' Sex ' )
self . JacketModel = msgin . readUint8 ( ' JacketModel ' )
self . JacketColor = msgin . readSerial ( 3 , ' JacketModel ' )
self . TrouserModel = msgin . readSerial ( 8 , ' TrouserModel ' )
self . TrouserColor = msgin . readSerial ( 3 , ' TrouserColor ' )
self . WeaponRightHand = msgin . readSerial ( 10 , ' WeaponRightHand ' )
self . WeaponLeftHand = msgin . readSerial ( 8 , ' WeaponLeftHand ' )
self . ArmModel = msgin . readSerial ( 8 , ' ArmModel ' )
self . ArmColor = msgin . readSerial ( 3 , ' ArmColor ' )
self . HatModel = msgin . readSerial ( 9 , ' HatModel ' )
self . HatColor = msgin . readSerial ( 3 , ' HatColor ' )
class SPropVisualB ( ) :
def __init__ ( self ) :
self . Name = " " #: 16;
self . HandsModel = 0 #: 9; // max: 512 current: 90
self . HandsColor = 0 #: 3; // max: 8 current: 8
self . FeetModel = 0 #: 9; // max: 512 current: 94
self . FeetColor = 0 #: 3; // max: 8 current: 8
self . RTrail = 0 #: 4;
self . LTrail = 0 #: 3;
self . NotUsed = 0 # 17 : # not used -> just to complete 64 bit
def read ( self , msgin ) :
self . Name = msgin . readSerial ( 16 , ' Name ' )
self . HandsModel = msgin . readSerial ( 9 , ' HandsModel ' )
self . HandsColor = msgin . readSerial ( 3 , ' HandsColor ' )
self . FeetModel = msgin . readSerial ( 9 , ' FeetModel ' )
self . FeetColor = msgin . readSerial ( 3 , ' FeetColor ' )
self . RTrail = msgin . readSerial ( 4 , ' RTrail ' )
self . LTrail = msgin . readSerial ( 3 , ' LTrail ' )
self . NotUsed = msgin . readSerial ( 17 , ' NotUsed ' )
class SPropVisualC ( ) :
def __init__ ( self ) :
self . MorphTarget1 = 0 # : 3; // max: 8 current: 8
self . MorphTarget2 = 0 # : 3; // max: 8 current: 8
self . MorphTarget3 = 0 # : 3; // max: 8 current: 8
self . MorphTarget4 = 0 # : 3; // max: 8 current: 8
self . MorphTarget5 = 0 # : 3; // max: 8 current: 8
self . MorphTarget6 = 0 # : 3; // max: 8 current: 8
self . MorphTarget7 = 0 # : 3; // max: 8 current: 8
self . MorphTarget8 = 0 # : 3; // max: 8 current: 8
self . EyesColor = 0 # : 3; // max: 8 current: 8
self . Tattoo = 0 # : 7; // max: 128 current: 64
self . CharacterHeight = 0 # : 4; // max: 16 current: 16
self . TorsoWidth = 0 # : 4; // max: 16 current: 16
self . ArmsWidth = 0 # : 4; // max: 16 current: 16
self . LegsWidth = 0 # : 4; // max: 16 current: 16
self . BreastSize = 0 # : 4; // max: 16 current: 16
self . NotUsed = 0 # 10 : # not used -> just to complete 64 bit
def read ( self , msgin ) :
self . MorphTarget1 = msgin . readSerial ( 3 , ' MorphTarget1 ' )
self . MorphTarget2 = msgin . readSerial ( 3 , ' MorphTarget2 ' )
self . MorphTarget3 = msgin . readSerial ( 3 , ' MorphTarget3 ' )
self . MorphTarget4 = msgin . readSerial ( 3 , ' MorphTarget4 ' )
self . MorphTarget5 = msgin . readSerial ( 3 , ' MorphTarget5 ' )
self . MorphTarget6 = msgin . readSerial ( 3 , ' MorphTarget6 ' )
self . MorphTarget7 = msgin . readSerial ( 3 , ' MorphTarget7 ' )
self . MorphTarget8 = msgin . readSerial ( 3 , ' MorphTarget8 ' )
self . EyesColor = msgin . readSerial ( 3 , ' EyesColor ' )
self . Tattoo = msgin . readSerial ( 7 , ' Tattoo ' )
self . CharacterHeight = msgin . readSerial ( 4 , ' CharacterHeight ' )
self . TorsoWidth = msgin . readSerial ( 4 , ' TorsoWidth ' )
self . ArmsWidth = msgin . readSerial ( 4 , ' ArmsWidth ' )
self . LegsWidth = msgin . readSerial ( 4 , ' LegsWidth ' )
self . BreastSize = msgin . readSerial ( 4 , ' BreastSize ' )
self . NotUsed = msgin . readSerial ( 10 , ' NotUsed ' )
class CCharacterSummary ( ) :
def __init__ ( self ) :
self . version = - 1
self . Mainland = 0 # CSessionId
self . Name = " "
self . People = 142
self . Location = 0
self . sPropVisualA = SPropVisualA ( )
self . sPropVisualB = SPropVisualB ( )
self . sPropVisualC = SPropVisualC ( )
self . sheetId = 0
self . Title = ECharacterTitle . NB_CHARACTER_TITLE
self . CharacterSlot = 255
self . InRingSession = False
self . HasEditSession = False
self . InNewbieland = False
def read ( self , msgin ) :
'''
khanat - opennel - code / code / ryzom / common / src / game_share / character_summary . cpp # void CCharacterSummary::serial(NLMISC::IStream &f)
'''
self . version = msgin . readUint8 ( ' version ' )
self . Mainland = msgin . readUint32 ( ' Mainland ' )
self . Name = msgin . readString ( ' Name ' )
self . People = msgin . readSint32 ( ' People ' )
self . Location = msgin . readUint32 ( ' Location ' )
self . sPropVisualA . read ( msgin )
self . sPropVisualB . read ( msgin )
self . sPropVisualC . read ( msgin )
self . sheetId = msgin . readUint32 ( ' SheetId ' )
self . Title = msgin . readSint32 ( ' Title ' ) # see ECharacterTitle
self . CharacterSlot = msgin . readUint8 ( ' CharacterSlot ' )
self . InRingSession = msgin . readBool ( ' InRingSession ' )
self . HasEditSession = msgin . readBool ( ' HasEditSession ' )
self . InNewbieland = msgin . readBool ( ' InNewbieland ' )
# f.serial (CharacterSlot);
# f.serial (InRingSession);
# f.serial (HasEditSession);
# if (serialNB)
# f.serial (InNewbieland);
2019-06-04 19:19:06 +00:00
class World ( ) :
def __init__ ( self , log ) :
self . log = log
self . GenericMultiPartTemp = { }
self . timestamp = 0
2019-06-12 21:14:56 +00:00
self . ServerPeopleActive = 255
self . ServerCareerActive = 255
self . CharacterSummaries = [ ]
2019-06-04 19:19:06 +00:00
def addGenericMultiPartTemp ( self , id ) :
self . GenericMultiPartTemp . setdefault ( id , CGenericMultiPartTemp ( self . log ) )
2019-06-12 21:14:56 +00:00
def setGenericMultiPartTemp ( self , Number , Part , NbBlock , PartCont , decodeImpulse ) :
self . GenericMultiPartTemp [ Number ] . set ( Number , Part , NbBlock , PartCont , decodeImpulse )
2019-06-04 19:19:06 +00:00
2019-05-19 13:23:03 +00:00
class CPersistentDataRecord :
def __init__ ( self , log ) :
self . log = log
self . TokenTable = [ ]
self . ArgTable = [ ]
self . StringTable = [ ]
self . ReadingStructStack = [ ]
self . offsetToken = 0
self . ArgOffset = 0
self . version = 0
self . totalSize = 0
self . tokenCount = 0
self . argCount = 0
self . stringCount = 0
self . stringsSize = 0
self . CBNPFile = [ ]
self . Categories = [ ]
def show ( self ) :
for x in self . CBNPFile :
self . log . debug ( " File: %s " % str ( x ) )
for x in self . Categories :
self . log . debug ( " Categorie: %s " % str ( x ) )
# ---------------- Manipulate Token ----------------
# +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+
# | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
# +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+
# | Token ID | Token Type |
# +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+
def token2Type ( self , token , extend ) : # persistent_data_inline.h:1102 CPersistentDataRecord::CArg::TType CPersistentDataRecord::CArg::token2Type(uint32 token,bool extend)
self . log . debug ( " token: %d , extend: %d " % ( token , extend ) )
if token == Card . BEGIN_TOKEN :
return TType . STRUCT_BEGIN
elif token == Card . END_TOKEN :
return TType . STRUCT_END
elif token == Card . FLAG_TOKEN :
return TType . FLAG
elif token == Card . SINT_TOKEN :
if extend :
return TType . SINT64
else :
return TType . SINT32
elif token == Card . UINT_TOKEN :
if extend :
return TType . UINT64
else :
return TType . UINT32
elif token == Card . FLOAT_TOKEN :
if extend :
return TType . FLOAT64
else :
return TType . FLOAT32
elif token == Card . STRING_TOKEN :
if extend :
return TType . EXTEND_TYPE
else :
return TType . STRING
self . log . error ( ' This should never happen! ' )
sys . exit ( 2 )
def type2Token ( self , type ) : # persistent_data_inline.h:1118 CPersistentDataRecord::TToken CPersistentDataRecord::CArg::type2Token(uint32 type)
self . log . debug ( " type: %d " % ( type ) )
if type == TType . STRUCT_BEGIN :
return Card . BEGIN_TOKEN
elif type == TType . STRUCT_END :
return Card . END_TOKEN
elif type == TType . FLAG :
return Card . FLAG_TOKEN
elif type == TType . SINT32 :
return Card . SINT_TOKEN
elif type == TType . UINT32 :
return Card . UINT_TOKEN
elif type == TType . FLOAT32 :
return Card . FLOAT_TOKEN
elif type == TType . STRING :
return Card . STRING_TOKEN
elif type == TType . SINT64 :
return Card . SINT_TOKEN
elif type == TType . UINT64 :
return Card . UINT_TOKEN
elif type == TType . FLOAT64 :
return Card . FLOAT_TOKEN
elif type == TType . EXTEND_TYPE :
return Card . STRING_TOKEN
self . log . error ( ' This should never happen! ' )
sys . exit ( 2 )
def peekNextToken ( self ) :
token = self . TokenTable [ self . offsetToken ]
self . log . debug ( " [ %d ] token: %d " % ( self . offsetToken , token ) )
return token / / 8 # persistent_data_inline.h:308 CPersistentDataRecord::TToken CPersistentDataRecord::peekNextToken() # _TokenTable[_TokenOffset]>>3;
def peekNextTokenType ( self ) : # persistent_data_limit.h:308 CPersistentDataRecord::TToken CPersistentDataRecord::peekNextToken() const
self . log . debug ( " peekNextTokenType - old offset token: %d " % self . offsetToken )
if self . isEndOfData ( ) :
self . log . error ( ' Attempt to read past end of input data ' )
sys . exit ( 2 )
token = self . TokenTable [ self . offsetToken ]
tokenType = token & 7
if tokenType == Card . EXTEND_TOKEN :
if self . offsetToken + 1 > self . tokenCount :
self . log . error ( ' Attempt to read past end of input data ' )
sys . exit ( 2 )
tokenType = self . TokenTable [ self . offsetToken + 1 ]
self . log . debug ( " peekNextTokenType [ %d ] token: %d type: %d " % ( self . offsetToken , token , tokenType ) )
return self . token2Type ( tokenType , True )
self . log . debug ( " peekNextTokenType [ %d ] token: %d type: %d " % ( self . offsetToken , token , tokenType ) )
return self . token2Type ( tokenType , False )
def isEndOfData ( self ) :
if self . offsetToken == self . tokenCount :
return True
return False
def isEndOfStruct ( self ) :
if self . isEndOfData ( ) :
self . log . debug ( " isEndOfData " )
return True
elif len ( self . ReadingStructStack ) == 0 :
self . log . debug ( " ReadingStructStack " )
return False
elif self . peekNextTokenType ( ) != TType . STRUCT_END :
self . log . debug ( " peekNextTokenType != TType.STRUCT_END " )
return False
elif self . ReadingStructStack [ - 1 ] != self . peekNextToken ( ) :
self . log . error ( " Opening and closing structure tokens don ' t match " )
sys . exit ( 2 )
self . log . debug ( " isEndOfStruct " )
return True
def isStartOfStruct ( self ) :
if self . peekNextTokenType ( ) == TType . STRUCT_BEGIN :
return True
return False
def popStructBegin ( self , token ) :
if self . peekNextToken ( ) != token :
self . log . error ( ' Attempting to enter a structure with the wrong delimiting token ' )
sys . exit ( 2 )
if self . peekNextTokenType ( ) != TType . STRUCT_BEGIN :
self . log . error ( ' Attempting to leave a structure with the wrong delimiting token type ' )
sys . exit ( 2 )
self . ReadingStructStack . append ( token )
self . offsetToken + = 1
def popStructEnd ( self , token ) :
if len ( self . ReadingStructStack ) == 0 :
self . log . error ( ' Attempting to pop end of a structure with nothing left in the open structure stack ' )
sys . exit ( 2 )
nextToken = self . peekNextToken ( )
topToken = self . ReadingStructStack [ - 1 ]
if topToken != token :
self . log . error ( ' Attempting to pop end of a structure with the wrong delimiting token ' )
sys . exit ( 2 )
if nextToken != token :
self . log . error ( ' Attempting to pop end of a structure with the wrong delimiting token ' )
sys . exit ( 2 )
if self . peekNextTokenType ( ) != TType . STRUCT_END :
self . log . error ( ' Attempting to leave a structure with the wrong delimiting token type ' )
sys . exit ( 2 )
del self . ReadingStructStack [ - 1 ]
self . offsetToken + = 1
# ---------------- Manipulate StringTable ----------------
def lookupString ( self , idx ) :
if idx > = self . stringCount :
self . log . error ( " Attempting to access past end of string table " )
sys . exit ( 2 )
return self . StringTable [ idx ]
# ---------------- Manipulate Arg ----------------
def peekNextArg ( self ) : # persistent_data_limit.h:339 CPersistentDataRecord::peekNextArg(CPersistentDataRecord::CArg& result) const
_type = self . peekNextTokenType ( )
result = CArg ( )
result . write_Type ( _type )
result . write_Type64 ( False )
self . log . debug ( " peekNextArg - Type: %d ArgOffset: %d " % ( _type , self . ArgOffset ) )
if result . isExtended ( ) :
self . log . debug ( " Extended " )
result . write_i32_1 ( self . ArgTable [ self . ArgOffset ] )
result . write_i32_2 ( self . ArgTable [ self . ArgOffset + 1 ] )
if result . read_Type ( ) == TType . EXTEND_TYPE and result . read_ExType ( ) == TExtendType . ET_64_BIT_EXTENDED_TYPES :
result . write_ex32_2 ( self . ArgTable [ self . ArgOffset + 2 ] ) ;
result . write_Type64 ( True )
elif not result . isFlag ( ) :
# result._Value.i32_1 = _ArgTable[_ArgOffset];
result . write_i32_1 ( self . ArgTable [ self . ArgOffset ] )
self . log . debug ( " peekNextArg - id : %d " % result . read_i32_1 ( ) )
if result . read_Type ( ) == TType . STRING :
result . write_String ( self . lookupString ( result . read_i32_1 ( ) ) )
self . log . debug ( " peekNextArg - String: %s " % result . read_String ( ) )
return result
def popNextArg ( self , token ) : # persistent_data_limit.h:414 CPersistentDataRecord::popNextArg(TToken token,CPersistentDataRecord::CArg& result)
result = self . peekNextArg ( )
if result . isFlag ( ) :
self . offsetToken + = 1
elif result . isExtended ( ) :
self . ArgOffset + = 2
self . offsetToken + = 2
if result . read_Type ( ) == TType . EXTEND_TYPE and result . read_ExType ( ) == TExtendType . ET_64_BIT_EXTENDED_TYPES :
self . ArgOffset + = 1
self . offsetToken + = 1
else :
self . ArgOffset + = 1
self . offsetToken + = 1
self . log . debug ( " popNextArg - Arg: %d " , result . read_i32_1 ( ) )
return result
def popString ( self , token ) :
TempArg = self . popNextArg ( token )
return TempArg . asString ( )
def popUint32 ( self , token ) :
TempArg = self . popNextArg ( token )
return TempArg . asUint ( )
def popBool ( self , token ) :
TempArg = self . popNextArg ( token )
return TempArg . asUint ( ) != 0
# ---------------- Read Data ----------------
def readFromBinFile ( self , filename ) : # persistent_data.cpp:835 # bool CPersistentDataRecord::fromBuffer(const char *src, uint32 bufferSize)
self . log . debug ( ' Read Bin File %s ' % filename )
with open ( filename , " rb " ) as fp :
buffer = fp . read ( )
fp . close ( )
self . version = int . from_bytes ( buffer [ 0 : 4 ] , byteorder = ' little ' , signed = False )
self . totalSize = int . from_bytes ( buffer [ 4 : 8 ] , byteorder = ' little ' , signed = False )
self . tokenCount = int . from_bytes ( buffer [ 8 : 12 ] , byteorder = ' little ' , signed = False )
self . argCount = int . from_bytes ( buffer [ 12 : 16 ] , byteorder = ' little ' , signed = False )
self . stringCount = int . from_bytes ( buffer [ 16 : 20 ] , byteorder = ' little ' , signed = False )
self . stringsSize = int . from_bytes ( buffer [ 20 : 24 ] , byteorder = ' little ' , signed = False )
offset = 24
self . log . debug ( " version: %d , totalSize: %d , tokenCount: %d , argCount: %d , stringCount: %d , stringsSize: %d " % ( self . version , self . totalSize , self . tokenCount , self . argCount , self . stringCount , self . stringsSize ) )
if len ( buffer ) != self . totalSize :
self . log . error ( " Failed to parse buffer due to invalid header (file: %s , size: %d , size define: %d ) " % ( filename , len ( buffer ) , self . totalSize ) )
sys . exit ( 2 )
if self . version > 0 :
self . log . error ( " PDR ERROR: Wrong file format version! (file: %s , version: %d ) " % ( filename , self . version ) )
sys . exit ( 2 )
if ( self . stringCount != 0 and self . stringsSize == 0 ) or ( self . stringCount == 0 and self . stringsSize != 0 ) :
self . log . error ( " PDR ERROR: Invalid string table parameters! (file: %s , stringCount: %d , stringsSize: %d ) " % ( filename , self . stringCount , self . stringsSize ) )
sys . exit ( 2 )
# i = offset+tokenCount*sizeof(TToken)+argCount*sizeof(uint32)+stringsSize
i = offset + self . tokenCount * 2 + self . argCount * 4 + self . stringsSize ;
if self . totalSize != i :
self . log . error ( " PDR ERROR: Invalid source data (file: %s , totalSize: %d != datasize: %s ) " % ( filename , self . totalSize , i ) )
sys . exit ( 2 )
# READ the tokens
self . TokenTable = [ ]
for i in range ( 0 , self . tokenCount ) :
tmp = int . from_bytes ( buffer [ offset : offset + 2 ] , byteorder = ' little ' , signed = False )
self . log . debug ( " token %5d => %3d id: %3d type: %d " % ( i , tmp , tmp / / 8 , tmp & 7 ) )
self . TokenTable . append ( tmp )
offset + = 2
# READ the arguments
self . ArgTable = [ ]
for i in range ( 0 , self . argCount ) :
tmp = int . from_bytes ( buffer [ offset : offset + 4 ] , byteorder = ' little ' , signed = False )
self . ArgTable . append ( tmp )
offset + = 4
# READ the string table data
if self . stringsSize != 0 :
chaine = ' '
self . StringTable = [ ]
while offset < self . totalSize :
car = buffer [ offset : offset + 1 ] . decode ( )
if car != ' \0 ' :
chaine + = car
else :
self . StringTable . append ( chaine )
chaine = ' '
offset + = 1
self . log . debug ( self . StringTable )
if chaine != ' ' :
self . log . error ( " PDR ERROR: Too few strings found in string table (file: %s ) " % ( filename ) )
sys . exit ( 2 )
self . log . debug ( " Red %s " % filename )
def decrypt_token ( self ) :
i = 0
lvl = 0
posArg = 0
extend = False
extend64 = False
result = CArg ( )
print ( " ^ Position ^ Token ^ " )
for value in self . TokenTable :
print ( " | %5d | %3d | " % ( i , value ) )
i + = 1
i = 0
print ( " ^ Position ^ Argument ^ " )
for value in self . ArgTable :
print ( " | %5d | %3d | " % ( i , value ) )
i + = 1
i = 0
print ( " ^ Position ^ String ^ " )
for value in self . StringTable :
print ( " | %5d | %s | " % ( i , value ) )
i + = 1
i = 0
print ( " ^ Position ^ Niveau ^ Token ^ Token ID ^^ Token Type (Card) ^^^ Result ^ " )
print ( " ^ ^^ (entrée) ^ Valeur ^ Quoi ^ Valeur ^ Card ^ Type ^ ^ " )
for token in self . TokenTable :
tokenId = token / / 8
tokenTypeValue = token & 7
result . write_String ( " - " )
if tokenTypeValue == 0 :
tokenCard = ' BEGIN_TOKEN '
tokenType = ' STRUCT_BEGIN '
result . write_Type ( TType . STRUCT_BEGIN )
if lvl < = 1 :
print ( " | ||||||| " )
lvl + = 1
elif tokenTypeValue == 1 :
tokenCard = ' END_TOKEN '
tokenType = ' STRUCT_END '
result . write_Type ( TType . STRUCT_END )
extend = False
extend64 = False
elif tokenTypeValue == 2 :
tokenCard = ' SINT_TOKEN '
if extend :
tokenType = ' SINT64 '
result . write_Type ( TType . SINT64 )
result . write_i32_1 ( self . ArgTable [ posArg ] )
result . write_i32_2 ( self . ArgTable [ posArg + 1 ] )
if extend64 :
result . write_ex32_2 ( self . ArgTable [ posArg + 2 ] ) ;
posArg + = 3
else :
posArg + = 2
else :
tokenType = ' SINT32 '
result . write_Type ( TType . SINT32 )
result . write_i32_1 ( self . ArgTable [ posArg ] )
posArg + = 1
extend = False
extend64 = False
elif tokenTypeValue == 3 :
tokenCard = ' UINT_TOKEN '
if extend :
tokenType = ' UINT64 '
result . write_Type ( TType . UINT64 )
result . write_i32_1 ( self . ArgTable [ posArg ] )
result . write_i32_2 ( self . ArgTable [ posArg + 1 ] )
if extend64 :
result . write_ex32_2 ( self . ArgTable [ posArg + 2 ] ) ;
posArg + = 3
else :
posArg + = 2
else :
tokenType = ' UINT32 '
result . write_Type ( TType . UINT32 )
result . write_i32_1 ( self . ArgTable [ posArg ] )
posArg + = 1
extend = False
extend64 = False
elif tokenTypeValue == 4 :
tokenCard = ' FLOAT_TOKEN '
if extend :
tokenType = ' FLOAT64 '
result . write_Type ( TType . FLOAT64 )
result . write_i32_1 ( self . ArgTable [ posArg ] )
result . write_i32_2 ( self . ArgTable [ posArg + 1 ] )
if extend64 :
result . write_ex32_2 ( self . ArgTable [ posArg + 2 ] ) ;
posArg + = 3
else :
posArg + = 2
else :
tokenType = ' FLOAT32 '
result . write_Type ( TType . FLOAT32 )
result . write_i32_1 ( self . ArgTable [ posArg ] )
posArg + = 1
extend = False
extend64 = False
elif tokenTypeValue == 5 :
tokenCard = ' STRING_TOKEN '
if extend :
tokenType = ' EXTEND_TYPE '
result . write_Type ( TType . EXTEND_TYPE )
result . write_i32_1 ( self . ArgTable [ posArg ] )
result . write_i32_2 ( self . ArgTable [ posArg + 1 ] )
if extend64 :
result . write_ex32_2 ( self . ArgTable [ posArg + 2 ] ) ;
posArg + = 3
else :
posArg + = 2
else :
tokenType = ' STRING '
result . write_Type ( TType . STRING )
result . write_i32_1 ( self . ArgTable [ posArg ] )
tmp = result . read_i32_1 ( )
result . write_String ( self . StringTable [ tmp ] )
posArg + = 1
extend = False
extend64 = False
elif tokenType == 6 :
tokenCard = ' FLAG_TOKEN '
tokenType = ' FLAG '
result . write_Type ( TType . FLAG )
extend = False
extend64 = False
elif tokenTypeValue == 7 :
if extend :
extend64 = True
tokenCard = ' EXTEND_TOKEN '
result . write_Type ( TType . EXTEND_TYPE )
tokenType = ' '
extend = True
# print("token %5d => %3d id:%3d [%s] type:%d [%s]" %(i, token, tokenId, self.StringTable[tokenId], tokenType, tokenCard))
print ( " | %5d | %3d | %3d | %3d | %s | %d | %s | %s | %s | " % ( i , lvl , token , tokenId , self . StringTable [ tokenId ] , tokenTypeValue , tokenCard , tokenType , result ) )
if tokenTypeValue == 1 :
lvl - = 1
i + = 1
def addString ( self , name ) : # persistent_data.cpp:100 uint16 CPersistentDataRecord::addString(const string& name)
for i in range ( 0 , len ( self . StringTable ) ) :
if self . StringTable [ i ] == name :
return i
self . StringTable . append ( name )
return len ( self . StringTable ) - 1
def CProductDescriptionForClient_apply ( self ) : # persistent_data_template.h:459 # void PERSISTENT_CLASS::apply(CPersistentDataRecord &pdr _PERSISTENT_APPLY_ARGS)
__Tok__MapKey = self . addString ( " __Key__ " )
__Tok__MapVal = self . addString ( " __Val__ " )
__Tok_Files = self . addString ( " _Files " )
__Tok_Categories = self . addString ( " _Categories " )
self . log . debug ( " MapKey: %d , MapVal: %d , Files: %d , Categories: %d " % ( __Tok__MapKey , __Tok__MapVal , __Tok_Files , __Tok_Categories ) )
while not self . isEndOfStruct ( ) :
nextToken = self . peekNextToken ( )
self . log . debug ( " nextToken: %d " % ( nextToken ) )
if nextToken == __Tok_Files :
self . popStructBegin ( __Tok_Files )
self . CBNPFileSet_apply ( )
self . popStructEnd ( __Tok_Files )
continue
elif nextToken == __Tok_Categories :
self . popStructBegin ( __Tok_Categories )
# (_Categories).apply(pdr);
self . CBNPCategorySet_apply ( )
self . popStructEnd ( __Tok_Categories )
continue
self . log . error ( " TODO " )
sys . exit ( 2 )
def CBNPFileSet_apply ( self ) :
__Tok__MapKey = self . addString ( " __Key__ " )
__Tok__MapVal = self . addString ( " __Val__ " )
__Tok_Files = self . addString ( " _Files " )
self . log . debug ( " MapKey: %d , MapVal: %d , Files: %d " % ( __Tok__MapKey , __Tok__MapVal , __Tok_Files ) )
while not self . isEndOfStruct ( ) :
nextToken = self . peekNextToken ( )
self . log . debug ( " nextToken: %d " % ( nextToken ) )
if nextToken == __Tok_Files :
self . popStructBegin ( __Tok_Files )
self . CBNPFile . append ( CBNPFile ( ) )
self . CBNPFile_apply ( self . CBNPFile [ - 1 ] )
self . popStructEnd ( __Tok_Files )
continue
self . log . error ( " TODO " )
sys . exit ( 2 )
def CBNPFile_apply ( self , _CBNPFile ) :
__Tok__MapKey = self . addString ( " __Key__ " )
__Tok__MapVal = self . addString ( " __Val__ " )
__Tok_FileName = self . addString ( " _FileName " )
__Tok_Versions = self . addString ( " _Versions " )
_FileName = None
self . log . debug ( " MapKey: %d , MapVal: %d , Filename: %d , Versions: %d " % ( __Tok__MapKey , __Tok__MapVal , __Tok_FileName , __Tok_Versions ) )
while not self . isEndOfStruct ( ) :
nextToken = self . peekNextToken ( )
self . log . debug ( " nextToken: %d " % ( nextToken ) )
if nextToken == __Tok_FileName :
_FileName = self . popString ( nextToken )
_CBNPFile . FileName = _FileName
self . log . debug ( " filename: %s " % _FileName )
continue
if nextToken == __Tok_Versions :
self . popStructBegin ( __Tok_Versions )
# vectAppend(_Versions).apply(pdr);
_CBNPFile . Versions . append ( CBNPFileVersion ( ) )
self . CBNPFileVersion_apply ( _CBNPFile . Versions [ - 1 ] )
self . popStructEnd ( __Tok_Versions )
continue
stack = [ ]
while True :
if self . isStartOfStruct ( ) :
stack . append ( self . peekNextToken ( ) )
self . popStructBegin ( stack )
elif self . isEndOfStruct ( ) :
self . popStructEnd ( stack [ - 1 ] )
if len ( stack ) > 0 :
del stack [ - 1 ]
else :
self . popNextArg ( self . peekNextToken ( ) )
if self . isEndOfData ( ) and len ( stack ) == 0 :
break
self . log . debug ( " CBNPFile: %s " % _CBNPFile )
def CBNPFileVersion_apply ( self , _CBNPFileVersion ) : # persistent_data_template.h:459 # void CBNPFileVersion::apply(CPersistentDataRecord &pdr )
__Tok__MapKey = self . addString ( " __Key__ " )
__Tok__MapVal = self . addString ( " __Val__ " )
__Tok_VersionNumber = self . addString ( " _VersionNumber " )
__Tok_FileSize = self . addString ( " _FileSize " )
__Tok_7ZFileSize = self . addString ( " _7ZFileSize " )
__Tok_FileTime = self . addString ( " _FileTime " )
__Tok_PatchSize = self . addString ( " _PatchSize " )
__Tok_HashKey = self . addString ( " _HashKey " )
self . log . debug ( " MapKey: %d , MapVal: %d , VersionNumber: %d , FileSize: %d , 7ZFileSize: %d , FileTime: %d , PatchSize: %d , HashKey: %d " % ( __Tok__MapKey , __Tok__MapVal , __Tok_VersionNumber , __Tok_FileSize , __Tok_7ZFileSize , __Tok_FileTime , __Tok_PatchSize , __Tok_HashKey ) )
while not self . isEndOfStruct ( ) :
nextToken = self . peekNextToken ( )
self . log . debug ( " nextToken: %d " % ( nextToken ) )
if nextToken == __Tok_VersionNumber :
self . log . debug ( " __Tok_VersionNumber " )
_CBNPFileVersion . VersionNumber = self . popUint32 ( __Tok_VersionNumber )
self . log . debug ( " VersionNumber: %s " % _CBNPFileVersion . VersionNumber )
continue
elif nextToken == __Tok_FileSize :
self . log . debug ( " __Tok_FileSize " )
_CBNPFileVersion . FileSize = self . popUint32 ( __Tok_FileSize )
self . log . debug ( " FileSize: %s " % _CBNPFileVersion . FileSize )
continue
elif nextToken == __Tok_7ZFileSize :
self . log . debug ( " __Tok_7ZFileSize " )
_CBNPFileVersion . v7ZFileSize = self . popUint32 ( __Tok_7ZFileSize )
self . log . debug ( " 7ZFileSize: %s " % _CBNPFileVersion . v7ZFileSize )
continue
elif nextToken == __Tok_FileTime :
self . log . debug ( " __Tok_FileTime " )
_CBNPFileVersion . FileTime = self . popUint32 ( __Tok_FileTime )
self . log . debug ( " FileTime: %s " % _CBNPFileVersion . FileTime )
continue
elif nextToken == __Tok_PatchSize :
self . log . debug ( " __Tok_PatchSize " )
_CBNPFileVersion . PatchSize = self . popUint32 ( __Tok_PatchSize )
self . log . debug ( " PatchSize: %s " % _CBNPFileVersion . PatchSize )
continue
elif nextToken == __Tok_HashKey :
self . log . debug ( " __Tok_HashKey " )
_CBNPFileVersion . HashKey . append ( self . popUint32 ( __Tok_HashKey ) )
self . log . debug ( " HashKey: %s " % _CBNPFileVersion . HashKey [ - 1 ] )
continue
# Vidage des autres clefs (inconnues)
stack = [ ]
while True :
if self . isStartOfStruct ( ) :
stack . append ( self . peekNextToken ( ) )
self . popStructBegin ( stack )
elif self . isEndOfStruct ( ) :
self . popStructEnd ( stack [ - 1 ] )
if len ( stack ) > 0 :
del stack [ - 1 ]
else :
self . popNextArg ( self . peekNextToken ( ) )
if self . isEndOfData ( ) and len ( stack ) == 0 :
break
def CBNPCategorySet_apply ( self ) : # persistent_data_template.h:459 # void CBNPCategorySet::apply(CPersistentDataRecord &pdr )
#__Tok__MapKey = self.addString("__Key__")
#__Tok__MapVal = self.addString("__Val__")
__Tok_Category = self . addString ( " _Category " )
while not self . isEndOfStruct ( ) :
nextToken = self . peekNextToken ( )
self . log . debug ( " nextToken: %d " % ( nextToken ) )
if nextToken == __Tok_Category :
self . log . debug ( " __Tok_Category " )
self . popStructBegin ( __Tok_Category )
self . Categories . append ( CBNPCategorySet ( ) )
self . CBNPCategory_apply ( self . Categories [ - 1 ] )
self . popStructEnd ( __Tok_Category )
continue
# Vidage des autres clefs (inconnues)
stack = [ ]
while True :
if self . isStartOfStruct ( ) :
stack . append ( self . peekNextToken ( ) )
self . popStructBegin ( stack )
elif self . isEndOfStruct ( ) :
self . popStructEnd ( stack [ - 1 ] )
if len ( stack ) > 0 :
del stack [ - 1 ]
else :
self . popNextArg ( self . peekNextToken ( ) )
if self . isEndOfData ( ) and len ( stack ) == 0 :
break
def CBNPCategory_apply ( self , _CBNPCategory ) : # persistent_data_template.h:459 # void CBNPCategory::apply(CPersistentDataRecord &pdr )
__Tok__MapKey = self . addString ( " __Key__ " )
__Tok__MapVal = self . addString ( " __Val__ " )
__Tok_Name = self . addString ( " _Name " )
__Tok_IsOptional = self . addString ( " _IsOptional " )
__Tok_UnpackTo = self . addString ( " _UnpackTo " )
__Tok_IsIncremental = self . addString ( " _IsIncremental " )
__Tok_CatRequired = self . addString ( " _CatRequired " )
__Tok_Hidden = self . addString ( " _Hidden " )
__Tok_Files = self . addString ( " _Files " )
self . log . debug ( " MapKey: %d , MapVal: %d , Name: %d , IsOptional: %d , UnpackTo: %d , IsIncremental: %d , CatRequired: %d , Hidden: %d , Files: %d " % ( __Tok__MapKey , __Tok__MapVal , __Tok_Name , __Tok_IsOptional , __Tok_UnpackTo , __Tok_IsIncremental , __Tok_CatRequired , __Tok_Hidden , __Tok_Files ) )
while not self . isEndOfStruct ( ) :
nextToken = self . peekNextToken ( )
self . log . debug ( " nextToken: %d " % ( nextToken ) )
if nextToken == __Tok_Name :
self . log . debug ( " __Tok_Name " )
_CBNPCategory . _Name = self . popString ( nextToken )
self . log . debug ( " _Name: %s " % _CBNPCategory . _Name )
continue
elif nextToken == __Tok_IsOptional :
self . log . debug ( " __Tok_IsOptional " )
_CBNPCategory . _IsOptional = self . popBool ( nextToken )
self . log . debug ( " _IsOptional: %s " % str ( _CBNPCategory . _IsOptional ) )
continue
elif nextToken == __Tok_UnpackTo :
self . log . debug ( " __Tok_UnpackTo " )
_CBNPCategory . _UnpackTo = self . popString ( nextToken )
self . log . debug ( " _UnpackTo: %s " % str ( _CBNPCategory . _UnpackTo ) )
continue
elif nextToken == __Tok_IsIncremental :
self . log . debug ( " __Tok_IsIncremental " )
_CBNPCategory . _IsIncremental = self . popBool ( nextToken )
self . log . debug ( " _IsIncremental: %s " % str ( _CBNPCategory . _IsIncremental ) )
continue
elif nextToken == __Tok_CatRequired :
self . log . debug ( " __Tok_CatRequired " )
_CBNPCategory . _CatRequired = self . popString ( nextToken )
self . log . debug ( " _CatRequired: %s " % str ( _CBNPCategory . _CatRequired ) )
continue
elif nextToken == __Tok_Hidden :
self . log . debug ( " __Tok_Hidden " )
_CBNPCategory . _Hidden = self . popBool ( nextToken )
self . log . debug ( " _Hidden: %s " % str ( _CBNPCategory . _Hidden ) )
continue
elif nextToken == __Tok_Files :
self . log . debug ( " __Tok_Files " )
2019-05-30 17:19:54 +00:00
_CBNPCategory . _Files . append ( self . popString ( nextToken ) )
2019-05-19 13:23:03 +00:00
self . log . debug ( " _Files: %s " % str ( _CBNPCategory . _Files ) )
continue
# Vidage des autres clefs (inconnues)
stack = [ ]
while True :
if self . isStartOfStruct ( ) :
stack . append ( self . peekNextToken ( ) )
self . popStructBegin ( stack )
elif self . isEndOfStruct ( ) :
self . popStructEnd ( stack [ - 1 ] )
if len ( stack ) > 0 :
del stack [ - 1 ]
else :
self . popNextArg ( self . peekNextToken ( ) )
if self . isEndOfData ( ) and len ( stack ) == 0 :
break
2019-06-02 13:45:55 +00:00
def getPowerOf2 ( v ) :
res = 1 ;
ret = 0 ;
while res < v :
ret + = 1
res * = 2
return ret
class DecodeImpulse ( ) :
2019-06-04 19:19:06 +00:00
def __init__ ( self , log , world ) :
2019-06-02 13:45:55 +00:00
'''
khanat - opennel - code / code / ryzom / client / src / net_manager . cpp # void initializeNetwork()
'''
self . log = log
self . msgXml = None
self . databaseXml = None
self . GenericMsgHeaderMngr = { }
self . initializeNetwork ( )
2019-06-04 19:19:06 +00:00
self . world = world
2019-06-02 13:45:55 +00:00
def impulseDatabaseUpdatePlayer ( self , msgin ) :
self . log . debug ( " TODO: %s " % msgin )
def impulseUpdateInventory ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseInitInventory ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseDatabaseUpdateBank ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseDatabaseInitBank ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseDatabaseResetBank ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseNoUserChar ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseUserChars ( self , msgin ) :
2019-06-12 21:14:56 +00:00
'''
khanat - opennel - code / code / ryzom / client / src / net_manager . cpp # void impulseUserChars(NLMISC::CBitMemStream &impulse)
'''
self . world . ServerPeopleActive = msgin . readUint8 ( ' ServerPeopleActive ' )
self . world . ServerCareerActive = msgin . readUint8 ( ' ServerCareerActive ' )
self . world . CharacterSummaries = [ ]
size = msgin . readUint32 ( ' CharacterSummaries:len ' )
for _ in range ( 0 , size ) :
tmp = CCharacterSummary ( )
tmp . read ( msgin )
self . world . CharacterSummaries . append ( tmp )
#_, CharacterSummaries = msgin.readCont('CharacterSummaries')
_ , shardNames = msgin . readCont ( ' shardNames ' )
# readPrivileges(impulse);
UserPrivileges = msgin . readString ( ' UserPrivileges ' )
FreeTrial = msgin . readBool ( ' FreeTrial ' )
_ , Mainlands = msgin . readCont ( ' Mainlands ' )
self . log . debug ( " Mesage UserChars: %s " % msgin . showAllData ( ) )
2019-06-02 13:45:55 +00:00
self . log . debug ( " TODO " )
2019-06-12 21:14:56 +00:00
2019-06-02 13:45:55 +00:00
def impulseUserChar ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseFarTP ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseServerReady ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseCharNameValid ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseShardId ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseServerQuitOk ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseServerQuitAbort ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseMailNotification ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseForumNotification ( self , msgin ) :
self . log . debug ( " TODO " )
def impulsePermanentBan ( self , msgin ) :
self . log . debug ( " TODO " )
def impulsePermanentUnban ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseChat ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseTell ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseFarTell ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseChat2 ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseDynString ( self , msgin ) :
self . log . debug ( " TODO " )
2019-06-04 19:19:06 +00:00
def inpulseDynStringInChatGroup ( self , msgin ) :
2019-06-02 13:45:55 +00:00
self . log . debug ( " TODO " )
def impulseTell2 ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseTP ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseTPWithSeason ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseCorrectPos ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseCombatEngageFailed ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseDynChatOpen ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseDynChatClose ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseBeginCast ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseTeamInvitation ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseTeamShareOpen ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseTeamShareInvalid ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseTeamShareClose ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseTeamContactInit ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseTeamContactCreate ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseTeamContactStatus ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseTeamContactRemove ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseExchangeInvitation ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseExchangeCloseInvitation ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseMountAbort ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseWhere ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseCounter ( self , msgin ) :
self . log . debug ( " TODO " )
def impulsePhraseSend ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseStringResp ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseReloadCache ( self , msgin ) :
2019-06-05 21:10:20 +00:00
self . world . timestamp = msgin . readUint32 ( ' timestamp ' )
2019-06-04 19:19:06 +00:00
self . log . debug ( " Reload Cache timestamp: %d " % self . world . timestamp )
2019-06-02 13:45:55 +00:00
self . log . debug ( " Message not read ( %d ) %s " % ( msgin . needRead ( ) , msgin . showLastData ( ) ) )
def impulseBotChatForceEnd ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseJournalInitCompletedMissions ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseJournalUpdateCompletedMissions ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseJournalAddCompass ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseJournalRemoveCompass ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseGuildJoinProposal ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseGuildAscensor ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseGuildLeaveAscensor ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseGuildAbortCreation ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseGuildOpenGuildWindow ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseGuildOpenInventory ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseGuildCloseInventory ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseGuildUpdatePlayerTitle ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseGuildUseFemaleTitles ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseCloseTempInv ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseRemoteAdmin ( self , msgin ) :
self . log . debug ( " TODO " )
def impulsePhraseDownLoad ( self , msgin ) :
self . log . debug ( " TODO " )
def impulsePhraseConfirmBuy ( self , msgin ) :
self . log . debug ( " TODO " )
def impulsePhraseAckExecuteCyclic ( self , msgin ) :
self . log . debug ( " TODO " )
def impulsePhraseAckExecuteNext ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseItemInfoSet ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseItemInfoRefreshVersion ( self , msgin ) :
self . log . debug ( " TODO " )
def impulsePrereqInfoSet ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseItemOpenRoomInventory ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseItemCloseRoomInventory ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseDeathRespawnPoint ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseDeathRespawn ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseDuelInvitation ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseDuelCancelInvitation ( self , msgin ) :
self . log . debug ( " TODO " )
def impulsePVPChallengeInvitation ( self , msgin ) :
self . log . debug ( " TODO " )
def impulsePVPChallengeCancelInvitation ( self , msgin ) :
self . log . debug ( " TODO " )
def impulsePVPFactionPushFactionWar ( self , msgin ) :
self . log . debug ( " TODO " )
def impulsePVPFactionPopFactionWar ( self , msgin ) :
self . log . debug ( " TODO " )
def impulsePVPFactionFactionWars ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseEncyclopediaUpdate ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseEncyclopediaInit ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseUserBars ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseUserPopup ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseEnterCrZoneProposal ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseCloseEnterCrZoneProposal ( self , msgin ) :
self . log . debug ( " TODO " )
2019-06-12 21:14:56 +00:00
def cbImpulsionGatewayOpen ( self , msgin ) :
2019-06-02 13:45:55 +00:00
self . log . debug ( " TODO " )
def cbImpulsionGatewayMessage ( self , msgin ) :
self . log . debug ( " TODO " )
2019-06-12 21:14:56 +00:00
def cbImpulsionGatewayClose ( self , msgin ) :
2019-06-02 13:45:55 +00:00
self . log . debug ( " TODO " )
def impulseOutpostChooseSide ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseOutpostDeclareWarAck ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseCombatFlyingChaScore1Delta ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseCombatFlyingTextItemSpecialEffectProc ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseCombatFlyingText ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseSetSeason ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseDssDown ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseSetNpcIconDesc ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseServerEventForMissionAvailability ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseSetNpcIconTimer ( self , msgin ) :
self . log . debug ( " TODO " )
def impulseDatabaseInitPlayer ( self , msgin ) :
self . log . debug ( " TODO " )
def initializeNetwork ( self ) :
self . GenericMsgHeaderMngr . setdefault ( ' DB_UPD_PLR ' , self . impulseDatabaseUpdatePlayer )
self . GenericMsgHeaderMngr . setdefault ( ' DB_INIT:PLR ' , self . impulseDatabaseInitPlayer )
self . GenericMsgHeaderMngr . setdefault ( " DB_UPD_INV " , self . impulseUpdateInventory )
self . GenericMsgHeaderMngr . setdefault ( " DB_INIT:INV " , self . impulseInitInventory )
self . GenericMsgHeaderMngr . setdefault ( " DB_GROUP:UPDATE_BANK " , self . impulseDatabaseUpdateBank )
self . GenericMsgHeaderMngr . setdefault ( " DB_GROUP:INIT_BANK " , self . impulseDatabaseInitBank )
self . GenericMsgHeaderMngr . setdefault ( " DB_GROUP:RESET_BANK " , self . impulseDatabaseResetBank )
self . GenericMsgHeaderMngr . setdefault ( " CONNECTION:NO_USER_CHAR " , self . impulseNoUserChar )
self . GenericMsgHeaderMngr . setdefault ( " CONNECTION:USER_CHARS " , self . impulseUserChars )
self . GenericMsgHeaderMngr . setdefault ( " CONNECTION:USER_CHAR " , self . impulseUserChar )
self . GenericMsgHeaderMngr . setdefault ( " CONNECTION:FAR_TP " , self . impulseFarTP )
self . GenericMsgHeaderMngr . setdefault ( " CONNECTION:READY " , self . impulseServerReady )
self . GenericMsgHeaderMngr . setdefault ( " CONNECTION:VALID_NAME " , self . impulseCharNameValid )
self . GenericMsgHeaderMngr . setdefault ( " CONNECTION:SHARD_ID " , self . impulseShardId )
self . GenericMsgHeaderMngr . setdefault ( " CONNECTION:SERVER_QUIT_OK " , self . impulseServerQuitOk )
self . GenericMsgHeaderMngr . setdefault ( " CONNECTION:SERVER_QUIT_ABORT " , self . impulseServerQuitAbort )
self . GenericMsgHeaderMngr . setdefault ( " CONNECTION:MAIL_AVAILABLE " , self . impulseMailNotification )
self . GenericMsgHeaderMngr . setdefault ( " CONNECTION:GUILD_MESSAGE_AVAILABLE " , self . impulseForumNotification )
self . GenericMsgHeaderMngr . setdefault ( " CONNECTION:PERMANENT_BAN " , self . impulsePermanentBan )
self . GenericMsgHeaderMngr . setdefault ( " CONNECTION:UNBAN " , self . impulsePermanentUnban )
self . GenericMsgHeaderMngr . setdefault ( " STRING:CHAT " , self . impulseChat )
self . GenericMsgHeaderMngr . setdefault ( " STRING:TELL " , self . impulseTell )
self . GenericMsgHeaderMngr . setdefault ( " STRING:FAR_TELL " , self . impulseFarTell )
self . GenericMsgHeaderMngr . setdefault ( " STRING:CHAT2 " , self . impulseChat2 )
self . GenericMsgHeaderMngr . setdefault ( " STRING:DYN_STRING " , self . impulseDynString )
2019-06-04 19:19:06 +00:00
self . GenericMsgHeaderMngr . setdefault ( " STRING:DYN_STRING_GROUP " , self . inpulseDynStringInChatGroup )
2019-06-02 13:45:55 +00:00
self . GenericMsgHeaderMngr . setdefault ( " STRING:TELL2 " , self . impulseTell2 )
self . GenericMsgHeaderMngr . setdefault ( " TP:DEST " , self . impulseTP )
self . GenericMsgHeaderMngr . setdefault ( " TP:DEST_WITH_SEASON " , self . impulseTPWithSeason )
self . GenericMsgHeaderMngr . setdefault ( " TP:CORRECT " , self . impulseCorrectPos )
self . GenericMsgHeaderMngr . setdefault ( " COMBAT:ENGAGE_FAILED " , self . impulseCombatEngageFailed )
self . GenericMsgHeaderMngr . setdefault ( " BOTCHAT:DYNCHAT_OPEN " , self . impulseDynChatOpen )
self . GenericMsgHeaderMngr . setdefault ( " BOTCHAT:DYNCHAT_CLOSE " , self . impulseDynChatClose )
self . GenericMsgHeaderMngr . setdefault ( " CASTING:BEGIN " , self . impulseBeginCast )
self . GenericMsgHeaderMngr . setdefault ( " TEAM:INVITATION " , self . impulseTeamInvitation )
self . GenericMsgHeaderMngr . setdefault ( " TEAM:SHARE_OPEN " , self . impulseTeamShareOpen )
self . GenericMsgHeaderMngr . setdefault ( " TEAM:SHARE_INVALID " , self . impulseTeamShareInvalid )
self . GenericMsgHeaderMngr . setdefault ( " TEAM:SHARE_CLOSE " , self . impulseTeamShareClose )
self . GenericMsgHeaderMngr . setdefault ( " TEAM:CONTACT_INIT " , self . impulseTeamContactInit )
self . GenericMsgHeaderMngr . setdefault ( " TEAM:CONTACT_CREATE " , self . impulseTeamContactCreate )
self . GenericMsgHeaderMngr . setdefault ( " TEAM:CONTACT_STATUS " , self . impulseTeamContactStatus )
self . GenericMsgHeaderMngr . setdefault ( " TEAM:CONTACT_REMOVE " , self . impulseTeamContactRemove )
self . GenericMsgHeaderMngr . setdefault ( " EXCHANGE:INVITATION " , self . impulseExchangeInvitation )
self . GenericMsgHeaderMngr . setdefault ( " EXCHANGE:CLOSE_INVITATION " , self . impulseExchangeCloseInvitation )
self . GenericMsgHeaderMngr . setdefault ( " ANIMALS:MOUNT_ABORT " , self . impulseMountAbort )
self . GenericMsgHeaderMngr . setdefault ( " DEBUG:REPLY_WHERE " , self . impulseWhere )
self . GenericMsgHeaderMngr . setdefault ( " DEBUG:COUNTER " , self . impulseCounter )
self . GenericMsgHeaderMngr . setdefault ( " STRING_MANAGER:PHRASE_SEND " , self . impulsePhraseSend )
self . GenericMsgHeaderMngr . setdefault ( " STRING_MANAGER:STRING_RESP " , self . impulseStringResp )
self . GenericMsgHeaderMngr . setdefault ( " STRING_MANAGER:RELOAD_CACHE " , self . impulseReloadCache )
self . GenericMsgHeaderMngr . setdefault ( " BOTCHAT:FORCE_END " , self . impulseBotChatForceEnd )
self . GenericMsgHeaderMngr . setdefault ( " JOURNAL:INIT_COMPLETED_MISSIONS " , self . impulseJournalInitCompletedMissions )
self . GenericMsgHeaderMngr . setdefault ( " JOURNAL:UPDATE_COMPLETED_MISSIONS " , self . impulseJournalUpdateCompletedMissions )
self . GenericMsgHeaderMngr . setdefault ( " JOURNAL:ADD_COMPASS " , self . impulseJournalAddCompass )
self . GenericMsgHeaderMngr . setdefault ( " JOURNAL:REMOVE_COMPASS " , self . impulseJournalRemoveCompass )
self . GenericMsgHeaderMngr . setdefault ( " GUILD:JOIN_PROPOSAL " , self . impulseGuildJoinProposal )
self . GenericMsgHeaderMngr . setdefault ( " GUILD:ASCENSOR " , self . impulseGuildAscensor )
self . GenericMsgHeaderMngr . setdefault ( " GUILD:LEAVE_ASCENSOR " , self . impulseGuildLeaveAscensor )
self . GenericMsgHeaderMngr . setdefault ( " GUILD:ABORT_CREATION " , self . impulseGuildAbortCreation )
self . GenericMsgHeaderMngr . setdefault ( " GUILD:OPEN_GUILD_WINDOW " , self . impulseGuildOpenGuildWindow )
self . GenericMsgHeaderMngr . setdefault ( " GUILD:OPEN_INVENTORY " , self . impulseGuildOpenInventory )
self . GenericMsgHeaderMngr . setdefault ( " GUILD:CLOSE_INVENTORY " , self . impulseGuildCloseInventory )
self . GenericMsgHeaderMngr . setdefault ( " GUILD:UPDATE_PLAYER_TITLE " , self . impulseGuildUpdatePlayerTitle )
self . GenericMsgHeaderMngr . setdefault ( " GUILD:USE_FEMALE_TITLES " , self . impulseGuildUseFemaleTitles )
self . GenericMsgHeaderMngr . setdefault ( " HARVEST:CLOSE_TEMP_INVENTORY " , self . impulseCloseTempInv )
self . GenericMsgHeaderMngr . setdefault ( " COMMAND:REMOTE_ADMIN " , self . impulseRemoteAdmin )
self . GenericMsgHeaderMngr . setdefault ( " PHRASE:DOWNLOAD " , self . impulsePhraseDownLoad )
self . GenericMsgHeaderMngr . setdefault ( " PHRASE:CONFIRM_BUY " , self . impulsePhraseConfirmBuy )
self . GenericMsgHeaderMngr . setdefault ( " PHRASE:EXEC_CYCLIC_ACK " , self . impulsePhraseAckExecuteCyclic )
self . GenericMsgHeaderMngr . setdefault ( " PHRASE:EXEC_NEXT_ACK " , self . impulsePhraseAckExecuteNext )
self . GenericMsgHeaderMngr . setdefault ( " ITEM_INFO:SET " , self . impulseItemInfoSet )
self . GenericMsgHeaderMngr . setdefault ( " ITEM_INFO:REFRESH_VERSION " , self . impulseItemInfoRefreshVersion )
self . GenericMsgHeaderMngr . setdefault ( " MISSION_PREREQ:SET " , self . impulsePrereqInfoSet )
self . GenericMsgHeaderMngr . setdefault ( " ITEM:OPEN_ROOM_INVENTORY " , self . impulseItemOpenRoomInventory )
self . GenericMsgHeaderMngr . setdefault ( " ITEM:CLOSE_ROOM_INVENTORY " , self . impulseItemCloseRoomInventory )
self . GenericMsgHeaderMngr . setdefault ( " DEATH:RESPAWN_POINT " , self . impulseDeathRespawnPoint )
self . GenericMsgHeaderMngr . setdefault ( " DEATH:RESPAWN " , self . impulseDeathRespawn )
self . GenericMsgHeaderMngr . setdefault ( " DUEL:INVITATION " , self . impulseDuelInvitation )
self . GenericMsgHeaderMngr . setdefault ( " DUEL:CANCEL_INVITATION " , self . impulseDuelCancelInvitation )
self . GenericMsgHeaderMngr . setdefault ( " PVP_CHALLENGE:INVITATION " , self . impulsePVPChallengeInvitation )
self . GenericMsgHeaderMngr . setdefault ( " PVP_CHALLENGE:CANCEL_INVITATION " , self . impulsePVPChallengeCancelInvitation )
self . GenericMsgHeaderMngr . setdefault ( " PVP_FACTION:PUSH_FACTION_WAR " , self . impulsePVPFactionPushFactionWar )
self . GenericMsgHeaderMngr . setdefault ( " PVP_FACTION:POP_FACTION_WAR " , self . impulsePVPFactionPopFactionWar )
self . GenericMsgHeaderMngr . setdefault ( " PVP_FACTION:FACTION_WARS " , self . impulsePVPFactionFactionWars )
self . GenericMsgHeaderMngr . setdefault ( " ENCYCLOPEDIA:UPDATE " , self . impulseEncyclopediaUpdate )
self . GenericMsgHeaderMngr . setdefault ( " ENCYCLOPEDIA:INIT " , self . impulseEncyclopediaInit )
self . GenericMsgHeaderMngr . setdefault ( " USER:BARS " , self . impulseUserBars )
self . GenericMsgHeaderMngr . setdefault ( " USER:POPUP " , self . impulseUserPopup )
self . GenericMsgHeaderMngr . setdefault ( " MISSION:ASK_ENTER_CRITICAL " , self . impulseEnterCrZoneProposal )
self . GenericMsgHeaderMngr . setdefault ( " MISSION:CLOSE_ENTER_CRITICAL " , self . impulseCloseEnterCrZoneProposal )
self . GenericMsgHeaderMngr . setdefault ( " MODULE_GATEWAY:FEOPEN " , self . cbImpulsionGatewayOpen )
self . GenericMsgHeaderMngr . setdefault ( " MODULE_GATEWAY:GATEWAY_MSG " , self . cbImpulsionGatewayMessage )
2019-06-04 19:19:06 +00:00
self . GenericMsgHeaderMngr . setdefault ( " MODULE_GATEWAY:FECLOSE " , self . cbImpulsionGatewayClose )
2019-06-02 13:45:55 +00:00
self . GenericMsgHeaderMngr . setdefault ( " OUTPOST:CHOOSE_SIDE " , self . impulseOutpostChooseSide )
self . GenericMsgHeaderMngr . setdefault ( " OUTPOST:DECLARE_WAR_ACK " , self . impulseOutpostDeclareWarAck )
self . GenericMsgHeaderMngr . setdefault ( " COMBAT:FLYING_ChaScore1_DELTA " , self . impulseCombatFlyingChaScore1Delta )
self . GenericMsgHeaderMngr . setdefault ( " COMBAT:FLYING_TEXT_ISE " , self . impulseCombatFlyingTextItemSpecialEffectProc )
self . GenericMsgHeaderMngr . setdefault ( " COMBAT:FLYING_TEXT " , self . impulseCombatFlyingText )
self . GenericMsgHeaderMngr . setdefault ( " SEASON:SET " , self . impulseSetSeason )
self . GenericMsgHeaderMngr . setdefault ( " RING_MISSION:DSS_DOWN " , self . impulseDssDown )
self . GenericMsgHeaderMngr . setdefault ( " NPC_ICON:SET_DESC " , self . impulseSetNpcIconDesc )
self . GenericMsgHeaderMngr . setdefault ( " NPC_ICON:SVR_EVENT_MIS_AVL " , self . impulseServerEventForMissionAvailability )
self . GenericMsgHeaderMngr . setdefault ( " NPC_ICON:SET_TIMER " , self . impulseSetNpcIconTimer )
def sizeElement ( self , keys = None ) :
head = self . msgXml
if not keys :
return len ( head )
ret = len ( head )
for key in keys . split ( ' : ' ) :
for ele in head :
if ele . attrib [ ' name ' ] == key :
head = ele
ret = len ( head )
break
return ret
def searchElement ( self , keys ) :
ret = [ ]
head = self . msgXml
self . log . debug ( len ( head ) )
for key in keys . split ( ' : ' ) :
#print(key)
id = 0
for ele in head :
if ele . attrib [ ' name ' ] == key :
self . log . debug ( ' %s => %d ' % ( key , id ) )
ret . append ( id )
head = ele
break
id + = 1
return ret
def execute ( self , msgin ) :
head = self . msgXml
listpath = [ ]
while True :
nbBit = getPowerOf2 ( len ( head ) )
2019-06-05 21:10:20 +00:00
# def readSerial(self, nbits, name="", decode=True, typeName='', emulate=False):
id = msgin . readSerial ( nbBit , name = ' Ptr ' , typeName = ' Number ' , emulate = True )
2019-06-02 13:45:55 +00:00
ele = head [ id ]
name = ele . attrib [ ' name ' ]
listpath . append ( name )
fullname = ' : ' . join ( listpath )
2019-06-05 21:10:20 +00:00
id = msgin . readSerial ( nbBit , name = ' Ptr ' , typeName = ' MsgXML< ' + name + ' > ' )
2019-06-02 13:45:55 +00:00
if fullname in self . GenericMsgHeaderMngr :
self . log . debug ( " Found : %s " % fullname )
self . GenericMsgHeaderMngr [ fullname ] ( msgin )
2019-06-05 21:10:20 +00:00
self . log . debug ( " MessageXML decoded: %s " % msgin . showAllData ( ) )
2019-06-02 13:45:55 +00:00
return True
else :
#self.log.debug("Non trouve")
for ele in head :
if ele . attrib [ ' name ' ] == name :
head = ele
break
if head != ele :
self . log . error ( " Impossible to found %s " % fullname )
2019-06-05 21:10:20 +00:00
self . log . debug ( " MessageXML decoded: %s " % msgin . showAllData ( ) )
2019-06-02 13:45:55 +00:00
return False
2019-06-05 21:10:20 +00:00
self . log . debug ( " MessageXML decoded: %s " % msgin . showAllData ( ) )
2019-06-02 13:45:55 +00:00
return False
def loadMsg ( self , msgXml ) :
self . msgXml = msgXml
def loadDatabase ( self , databaseXml ) :
self . databaseXml = databaseXml
2019-05-31 17:25:04 +00:00
class CAction :
2019-06-04 19:19:06 +00:00
def __init__ ( self , slot , code , world ) :
2019-05-31 17:25:04 +00:00
self . Code = code
self . PropertyCode = code
self . Slot = slot
self . _Priority = 1
self . Timeout = 0
self . GameCycle = 0
2019-06-04 19:19:06 +00:00
self . world = world
2019-05-31 17:25:04 +00:00
def unpack ( self , message ) :
raise RuntimeError
def pack ( self , message ) :
raise RuntimeError
def serialIn ( self , msgin ) :
raise RuntimeError
def serialOut ( self , msgout ) :
raise RuntimeError
def size ( self ) :
raise RuntimeError
def getMaxSizeInBit ( self ) :
raise RuntimeError
def setPriority ( self , prio ) :
raise RuntimeError
def priority ( self ) :
raise RuntimeError
def getValue ( self ) :
raise RuntimeError
def setValue ( self , value ) :
raise RuntimeError
def isContinuous ( self ) :
raise RuntimeError
def reset ( self ) :
raise RuntimeError
def __str__ ( self ) :
return " [ %d , %d ] " % ( self . Code , self . Slot )
class CActionPosition ( CAction ) :
2019-06-04 19:19:06 +00:00
def __init__ ( self , slot , code , world ) :
super ( ) . __init__ ( slot , code , world )
2019-05-31 17:25:04 +00:00
2019-06-02 13:45:55 +00:00
def __str__ ( self ) :
return " CActionPosition " + super ( ) . __str__ ( )
2019-05-31 17:25:04 +00:00
class CActionSync ( CAction ) :
2019-06-04 19:19:06 +00:00
def __init__ ( self , slot , code , world ) :
super ( ) . __init__ ( slot , code , world )
2019-05-31 17:25:04 +00:00
2019-06-02 13:45:55 +00:00
def __str__ ( self ) :
return " CActionSync " + super ( ) . __str__ ( )
2019-05-31 17:25:04 +00:00
class CActionDisconnection ( CAction ) :
2019-06-04 19:19:06 +00:00
def __init__ ( self , slot , code , world ) :
super ( ) . __init__ ( slot , code , world )
2019-05-31 17:25:04 +00:00
2019-06-02 13:45:55 +00:00
def __str__ ( self ) :
return " CActionDisconnection " + super ( ) . __str__ ( )
2019-05-31 17:25:04 +00:00
class CActionAssociation ( CAction ) :
2019-06-04 19:19:06 +00:00
def __init__ ( self , slot , code , world ) :
super ( ) . __init__ ( slot , code , world )
2019-05-31 17:25:04 +00:00
2019-06-02 13:45:55 +00:00
def __str__ ( self ) :
return " CActionAssociation " + super ( ) . __str__ ( )
2019-05-31 17:25:04 +00:00
class CActionDummy ( CAction ) :
2019-06-04 19:19:06 +00:00
def __init__ ( self , slot , code , world ) :
super ( ) . __init__ ( slot , code , world )
2019-05-31 17:25:04 +00:00
2019-06-02 13:45:55 +00:00
def __str__ ( self ) :
return " CActionDummy " + super ( ) . __str__ ( )
2019-05-31 17:25:04 +00:00
class CActionLogin ( CAction ) :
2019-06-04 19:19:06 +00:00
def __init__ ( self , slot , code , world ) :
super ( ) . __init__ ( slot , code , world )
2019-05-31 17:25:04 +00:00
2019-06-02 13:45:55 +00:00
def __str__ ( self ) :
return " CActionLogin " + super ( ) . __str__ ( )
2019-05-31 17:25:04 +00:00
class CActionTargetSlot ( CAction ) :
2019-06-04 19:19:06 +00:00
def __init__ ( self , slot , code , world ) :
super ( ) . __init__ ( slot , code , world )
2019-05-31 17:25:04 +00:00
2019-06-02 13:45:55 +00:00
def __str__ ( self ) :
return " CActionTargetSlot " + super ( ) . __str__ ( )
2019-05-31 17:25:04 +00:00
class CActionGeneric ( CAction ) :
2019-06-04 19:19:06 +00:00
def __init__ ( self , slot , code , world ) :
super ( ) . __init__ ( slot , code , world )
2019-05-31 17:25:04 +00:00
self . _Message = None
def unpack ( self , message ) :
2019-06-05 21:10:20 +00:00
size = message . readUint32 ( ' size ' )
self . _Message = message . readBitStreamUint8 ( size , ' message ' )
2019-06-02 13:45:55 +00:00
2019-06-06 20:21:35 +00:00
def pack ( self , msgout ) :
msgout . pushArrayUint8 ( self . _Message , len ( self . _Message ) )
2019-06-02 13:45:55 +00:00
def reset ( self ) :
self . _Message = None
def genericAction ( self , decodeImpulse ) :
decodeImpulse . execute ( self . _Message )
def __str__ ( self ) :
return " CActionGeneric " + super ( ) . __str__ ( ) + " [ " + self . _Message . showAllData ( ) + ' ] '
2019-05-31 17:25:04 +00:00
class CActionGenericMultiPart ( CAction ) :
2019-06-02 13:45:55 +00:00
'''
khanat - opennel - code / code / ryzom / common / src / game_share / action_generic_multi_part . h # class CActionGenericMultiPart
'''
2019-06-04 19:19:06 +00:00
def __init__ ( self , slot , code , world ) :
super ( ) . __init__ ( slot , code , world )
2019-05-31 17:25:04 +00:00
self . PartCont = [ ]
self . Number = 0
self . Part = 0
self . NbBlock = 0
def unpack ( self , message ) :
2019-06-05 21:10:20 +00:00
self . Number = message . readUint8 ( ' Number ' )
self . Part = message . readUint16 ( ' Part ' )
self . NbBlock = message . readUint16 ( ' NbBlock ' )
2019-05-31 17:25:04 +00:00
2019-06-05 21:10:20 +00:00
size = message . readUint32 ( ' size ' )
self . PartCont = message . readBitStreamUint8 ( size , ' PartCont ' )
2019-06-12 21:14:56 +00:00
self . log = logging . getLogger ( ' myLogger ' )
self . log . debug ( " unpack - Number: %d Part: %d NbBlock: %d " % ( self . Number , self . Part , self . NbBlock ) )
2019-06-02 13:45:55 +00:00
2019-06-06 20:21:35 +00:00
def pack ( self , msgout ) :
msgout . pushUint8 ( self . Number )
msgout . pushUint16 ( self . Part )
msgout . pushUint16 ( self . NbBlock )
msgout . pushArrayUint8 ( self . PartCont )
2019-06-02 13:45:55 +00:00
def reset ( self ) :
self . PartCont = [ ]
self . Number = 0
self . Part = 0
self . NbBlock = 0
def genericAction ( self , decodeImpulse ) :
'''
khanat - opennel - code / code / ryzom / client / src / network_connection . cpp # void CNetworkConnection::genericAction (CActionGenericMultiPart *agmp)
'''
self . log = logging . getLogger ( ' myLogger ' )
self . log . debug ( " Number: %d Part: %d NbBlock: %d " % ( self . Number , self . Part , self . NbBlock ) )
2019-06-04 19:19:06 +00:00
self . world . addGenericMultiPartTemp ( self . Number )
2019-06-12 21:14:56 +00:00
self . world . setGenericMultiPartTemp ( self . Number , self . Part , self . NbBlock , self . PartCont , decodeImpulse )
2019-06-02 13:45:55 +00:00
def __str__ ( self ) :
return " CActionGenericMultiPart " + super ( ) . __str__ ( ) + " [ " + str ( self . Number ) + ' , ' + str ( self . Part ) + ' , ' + str ( self . NbBlock ) + ' , ' + self . PartCont . showAllData ( ) + ' ] '
2019-05-31 17:25:04 +00:00
class CActionSint64 ( CAction ) :
2019-06-04 19:19:06 +00:00
def __init__ ( self , slot , code , world ) :
super ( ) . __init__ ( slot , code , world )
2019-05-31 17:25:04 +00:00
2019-06-02 13:45:55 +00:00
def __str__ ( self ) :
return " CActionSint64 " + super ( ) . __str__ ( )
2019-05-31 17:25:04 +00:00
2019-06-02 13:45:55 +00:00
class CActionFactory :
2019-06-04 19:19:06 +00:00
def __init__ ( self , log , world ) :
2019-06-02 13:45:55 +00:00
self . log = log
2019-06-04 19:19:06 +00:00
self . world = world
2019-06-02 13:45:55 +00:00
self . RegisteredAction = { }
self . RegisteredAction . setdefault ( TActionCode . ACTION_POSITION_CODE , [ ] )
self . RegisteredAction . setdefault ( TActionCode . ACTION_GENERIC_CODE , [ ] )
self . RegisteredAction . setdefault ( TActionCode . ACTION_GENERIC_MULTI_PART_CODE , [ ] )
self . RegisteredAction . setdefault ( TActionCode . ACTION_SINT64 , [ ] )
self . RegisteredAction . setdefault ( TActionCode . ACTION_SYNC_CODE , [ ] )
self . RegisteredAction . setdefault ( TActionCode . ACTION_DISCONNECTION_CODE , [ ] )
self . RegisteredAction . setdefault ( TActionCode . ACTION_ASSOCIATION_CODE , [ ] )
self . RegisteredAction . setdefault ( TActionCode . ACTION_LOGIN_CODE , [ ] )
self . RegisteredAction . setdefault ( TActionCode . ACTION_TARGET_SLOT_CODE , [ ] )
self . RegisteredAction . setdefault ( TActionCode . ACTION_DUMMY_CODE , [ ] )
def createFactory ( self , slot , code ) :
2019-05-31 17:25:04 +00:00
if code == TActionCode . ACTION_POSITION_CODE :
2019-06-02 13:45:55 +00:00
self . log . debug ( " Create CActionPosition " )
2019-06-04 19:19:06 +00:00
return CActionPosition ( slot , code , self . world )
2019-05-31 17:25:04 +00:00
elif code == TActionCode . ACTION_GENERIC_CODE :
2019-06-02 13:45:55 +00:00
self . log . debug ( " Create CActionGeneric " )
2019-06-04 19:19:06 +00:00
return CActionGeneric ( slot , code , self . world )
2019-05-31 17:25:04 +00:00
elif code == TActionCode . ACTION_GENERIC_MULTI_PART_CODE :
2019-06-02 13:45:55 +00:00
self . log . debug ( " Create CActionGenericMultiPart " )
2019-06-04 19:19:06 +00:00
return CActionGenericMultiPart ( slot , code , self . world )
2019-05-31 17:25:04 +00:00
elif code == TActionCode . ACTION_SINT64 :
2019-06-02 13:45:55 +00:00
self . log . debug ( " Create CActionSint64 " )
2019-06-04 19:19:06 +00:00
return CActionSint64 ( slot , code , self . world )
2019-05-31 17:25:04 +00:00
elif code == TActionCode . ACTION_SYNC_CODE :
2019-06-02 13:45:55 +00:00
self . log . debug ( " Create CActionSync " )
2019-06-04 19:19:06 +00:00
return CActionSync ( slot , code , self . world )
2019-05-31 17:25:04 +00:00
elif code == TActionCode . ACTION_DISCONNECTION_CODE :
2019-06-02 13:45:55 +00:00
self . log . debug ( " Create CActionDisconnection " )
2019-06-04 19:19:06 +00:00
return CActionDisconnection ( slot , code , self . world )
2019-05-31 17:25:04 +00:00
elif code == TActionCode . ACTION_ASSOCIATION_CODE :
2019-06-02 13:45:55 +00:00
self . log . debug ( " Create CActionAssociation " )
2019-06-04 19:19:06 +00:00
return CActionAssociation ( slot , code , self . world )
2019-05-31 17:25:04 +00:00
elif code == TActionCode . ACTION_LOGIN_CODE :
2019-06-02 13:45:55 +00:00
self . log . debug ( " Create CActionLogin " )
2019-06-04 19:19:06 +00:00
return CActionLogin ( slot , code , self . world )
2019-05-31 17:25:04 +00:00
elif code == TActionCode . ACTION_TARGET_SLOT_CODE :
2019-06-02 13:45:55 +00:00
self . log . debug ( " Create CActionTargetSlot " )
2019-06-04 19:19:06 +00:00
return CActionTargetSlot ( slot , code , self . world )
2019-05-31 17:25:04 +00:00
elif code == TActionCode . ACTION_DUMMY_CODE :
2019-06-02 13:45:55 +00:00
self . log . debug ( " Create CActionDummy " )
2019-06-04 19:19:06 +00:00
return CActionDummy ( slot , code , self . world )
2019-05-31 17:25:04 +00:00
else :
log = logging . getLogger ( ' myLogger ' )
log . warning ( ' create() try to create an unknown action ( %u ) ' % code )
raise RuntimeError
2019-06-02 13:45:55 +00:00
def create ( self , slot , code ) :
if code not in self . RegisteredAction :
log = logging . getLogger ( ' myLogger ' )
log . warning ( ' try to create an unknown action ( %u ) ' % code )
raise None
elif not self . RegisteredAction [ code ] :
self . log . debug ( " new CAction " )
action = self . createFactory ( slot , code )
action . reset ( )
return action
else :
self . log . debug ( " update CAction " )
action = self . RegisteredAction [ code ] [ - 1 ]
action . reset ( )
action . PropertyCode = code
action . Slot = slot
return action
2019-05-31 17:25:04 +00:00
def unpack ( self , msgin ) :
'''
khanat - opennel - code / code / ryzom / common / src / game_share / action_factory . cpp : CAction * CActionFactory : : unpack ( NLMISC : : CBitMemStream & message , NLMISC : : TGameCycle / * currentCycle * / )
'''
if msgin . needRead ( ) > = 8 :
2019-06-05 21:10:20 +00:00
shortcode = msgin . readBool ( ' shortcode ' )
2019-05-31 17:25:04 +00:00
if shortcode :
2019-06-05 21:10:20 +00:00
code = msgin . readSerial ( 2 , ' code ' )
2019-05-31 17:25:04 +00:00
else :
2019-06-05 21:10:20 +00:00
code = msgin . readUint8 ( ' code ' )
2019-05-31 17:25:04 +00:00
action = self . create ( INVALID_SLOT , code )
if action :
try :
action . unpack ( msgin ) ;
except RuntimeError :
log = logging . getLogger ( ' myLogger ' )
log . warning ( ' Missing code to unpack (code : %u ) ' % code )
raise RuntimeError
else :
log = logging . getLogger ( ' myLogger ' )
log . warning ( ' Unpacking an action with unknown code, skip it ( %u ) ' % code )
2019-06-02 13:45:55 +00:00
return action
2019-06-06 20:21:35 +00:00
def pack ( self , action , msgout ) :
if action . Code < 4 :
msgout . pushBool ( True )
msgout . internalSerial ( self . Code , 2 )
else :
msgout . pushBool ( False )
msgout . pushUint8 ( self . Code )
action . pack ( message )
class CActionBlock :
def __init__ ( self ) :
self . Cycle = 0
self . FirstPacket = 0
self . Actions = None
self . Sucess = True
def serial ( self , msgout , actionFactory ) :
msgout . pushUint32 ( self . Cycle )
msgout . pushUint8 ( len ( self . Actions ) )
for action in self . Actions :
# msgPosBefore = msgout.getPosInBit()
actionFactory . pack ( action , msgout )
# msgPosAfter = msgout.getPosInBit()
# actionSize = actionFactory.size(action)
2019-05-31 17:25:04 +00:00
class CImpulseDecoder :
'''
see : khanat - opennel - code / code / ryzom / client / src / impulse_decoder . cpp
'''
2019-06-04 19:19:06 +00:00
def __init__ ( self , log , world ) :
2019-06-02 13:45:55 +00:00
self . log = log
2019-06-04 19:19:06 +00:00
self . world = world
2019-05-31 17:25:04 +00:00
self . reset ( )
2019-06-04 19:19:06 +00:00
self . _CActionFactory = CActionFactory ( log , world )
2019-06-02 13:45:55 +00:00
def removeCAction ( self , action ) :
self . _CActionFactory . RegisteredAction [ action . Code ] . append ( action )
2019-05-31 17:25:04 +00:00
def decode ( self , msgin , receivedPacket , receivedAck , nextSentPacket ) :
2019-06-04 19:19:06 +00:00
self . log . debug ( " receivedPacket: %d receivedAck: %d nextSentPacket: %d " % ( receivedPacket , receivedAck , nextSentPacket ) )
2019-05-31 17:25:04 +00:00
actions = [ ]
for level in range ( 0 , 3 ) :
if level == 0 :
lAck = self . _LastAck0
channel = 0
elif level == 1 :
lAck = self . _LastAck1
channel = receivedPacket & 1
elif level == 2 :
lAck = self . _LastAck2
channel = receivedPacket & 3
keep = True
checkOnce = False
num = 0
2019-06-12 21:14:56 +00:00
self . log . debug ( " level: %d channel: %d lAck: %s " % ( level , channel , ' : ' . join ( [ str ( x ) for x in lAck ] ) ) )
2019-05-31 17:25:04 +00:00
# lastAck = lAck[channel]
while True :
2019-06-05 21:10:20 +00:00
next = msgin . readBool ( ' next: ' + str ( level ) + ' : ' + str ( channel ) )
2019-05-31 17:25:04 +00:00
if not next :
break
if not checkOnce :
checkOnce = True
keep = receivedAck > = lAck [ channel ]
2019-06-12 21:14:56 +00:00
self . log . debug ( " keep: %s [ %d => %d ] " % ( str ( keep ) , receivedAck , lAck [ channel ] ) )
2019-05-31 17:25:04 +00:00
if keep :
lAck [ channel ] = nextSentPacket
2019-06-04 19:19:06 +00:00
self . log . debug ( " lAck: %s " % ' : ' . join ( [ str ( x ) for x in lAck ] ) )
2019-05-31 17:25:04 +00:00
num + = 1
action = self . _CActionFactory . unpack ( msgin )
if keep :
2019-06-02 13:45:55 +00:00
self . log . debug ( " keep " )
2019-05-31 17:25:04 +00:00
actions . append ( action )
2019-06-02 13:45:55 +00:00
elif action :
self . log . debug ( " append " )
self . removeCAction ( action )
2019-05-31 17:25:04 +00:00
return actions
def reset ( self ) :
self . _LastAck0 = [ - 1 ]
self . _LastAck1 = [ - 1 , - 1 ]
self . _LastAck2 = [ - 1 , - 1 , - 1 , - 1 ]
2019-06-06 20:21:35 +00:00
class TStampQueue :
def __init__ ( self , first = None , second = None ) :
self . first = first
self . second = second
2019-05-19 13:23:03 +00:00
class ClientNetworkConnection :
2019-05-31 17:25:04 +00:00
'''
Partie client de la gestion de la communication reseau avec le serveur :
client :
code / ryzom / client / src / network_connection . cpp
server :
khanat - opennel - code / code / ryzom / server / src / frontend_service / fe_receive_sub . cpp # void CFeReceiveSub::handleReceivedMsg( CClientHost *clienthost )
'''
2019-05-19 13:23:03 +00:00
def __init__ ( self ,
2019-05-30 17:19:54 +00:00
khanat_host ,
khanat_port_frontend ,
2019-05-30 21:46:07 +00:00
LanguageCode = " fr " ,
checkMessageNumber = True ) :
2019-05-19 13:23:03 +00:00
self . log = logging . getLogger ( ' myLogger ' )
self . _CurrentSendNumber = 0
self . LanguageCode = LanguageCode
self . _QuitId = 0
2019-05-30 17:19:54 +00:00
self . _ConnectionState = TConnectionState . NotInitialised
2019-05-19 13:23:03 +00:00
self . UserAddr , self . UserKey , self . UserId = None , None , None
2019-05-30 17:19:54 +00:00
self . frontend = ( khanat_host , khanat_port_frontend )
2019-05-31 17:25:04 +00:00
self . _sock = None
2019-05-30 17:19:54 +00:00
self . _CurrentReceivedNumber = 0
self . _SystemMode = 0
self . _LastReceivedAck = 0
self . _LastReceivedNumber = 0
self . _LastAckInLongAck = 0
2019-05-30 17:37:42 +00:00
self . _MsgXmlMD5 = None
self . _DatabaseXmlMD5 = None
2019-05-30 18:40:42 +00:00
self . msgXml = None
self . databaseXml = None
2019-05-30 21:46:07 +00:00
self . _Synchronize = 0
self . _LatestSync = 0
self . _CurrentServerTick = 0
self . _MsPerTick = 0
self . _LCT = 100
self . _UpdateTime = 0
#self._UpdateTicks = 0
self . _ReceivedSync = False
self . _LastReceivedTime = 0
self . _LastReceivedPacketInBothModes = 0
self . _TotalMessages = 0
self . _TotalLostPackets = 0
self . checkMessageNumber = checkMessageNumber
self . _LastAckBit = 0
self . _AckBitMask = 0
2019-05-31 17:25:04 +00:00
self . _LongAckBitField = CBitSet ( )
self . _LatestSyncTime = 0
2019-06-04 19:19:06 +00:00
self . world = World ( self . log )
self . _ImpulseDecoder = CImpulseDecoder ( self . log , self . world )
2019-05-31 17:25:04 +00:00
self . _LongAckBitField . resize ( 1024 )
2019-05-31 23:45:35 +00:00
self . _LatestProbeTime = 0
self . _LatestProbe = 0
self . _LatestProbes = [ ]
self . _LatestQuitTime = 0
self . _ReceivedAckQuit = False
2019-06-02 13:45:55 +00:00
self . _Actions = [ ]
self . _PacketStamps = [ ]
2019-06-04 19:19:06 +00:00
self . decodeImpulse = DecodeImpulse ( self . log , self . world )
2019-06-06 20:21:35 +00:00
self . _InstantPing = 0
self . _BestPing = 10000
self . _MsPerTick = 100
self . _LastSendTime = 0
2019-05-31 23:45:35 +00:00
def signal_exit ( self , sig , frame ) :
self . log . warning ( " Receive signal to quit program " )
self . sendSystemQuit ( )
sys . exit ( 0 )
2019-05-31 17:25:04 +00:00
def connect ( self ) :
2019-05-31 23:45:35 +00:00
signal . signal ( signal . SIGINT , self . signal_exit )
signal . signal ( signal . SIGTERM , self . signal_exit )
2019-05-31 17:25:04 +00:00
try :
self . _sock = socket . socket ( socket . AF_INET , # Internet
socket . SOCK_DGRAM ) # UDP
except :
self . log . error ( " Impossible to connect on khanat " )
return False
self . _ConnectionState = TConnectionState . Login
self . _LatestSyncTime = int ( time . clock_gettime ( 1 ) * 1000 )
return True
2019-05-19 13:23:03 +00:00
def cookiesInit ( self , UserAddr , UserKey , UserId ) :
self . UserAddr = UserAddr
self . UserKey = UserKey
self . UserId = UserId
def reset ( self ) :
self . _CurrentSendNumber + = 0
2019-05-31 17:25:04 +00:00
def buildSystemHeader ( self , msgout ) : # code/ryzom/client/src/network_connection.cpp # void CNetworkConnection::buildSystemHeader(NLMISC::CBitMemStream &msgout)
msgout . pushSint32 ( self . _CurrentSendNumber )
msgout . pushBool ( True ) # systemMode
2019-06-06 20:21:35 +00:00
self . _PacketStamps . append ( TStampQueue ( self . _CurrentSendNumber , self . _UpdateTime ) )
2019-06-04 19:19:06 +00:00
self . _CurrentSendNumber + = 1
2019-05-19 13:23:03 +00:00
def sendSystemLogin ( self ) : # code/ryzom/client/src/network_connection.cpp # void CNetworkConnection::sendSystemLogin()
if self . _sock is None :
raise ValueError
2019-05-31 17:25:04 +00:00
msgout = BitStream ( )
self . buildSystemHeader ( msgout )
msgout . pushUint8 ( CLFECOMMON . SYSTEM_LOGIN_CODE )
msgout . pushUint32 ( self . UserAddr )
msgout . pushUint32 ( self . UserKey )
msgout . pushUint32 ( self . UserId )
msgout . pushString ( self . LanguageCode )
self . _sock . sendto ( msgout . toBytes ( ) , self . frontend )
2019-05-19 13:23:03 +00:00
self . _CurrentSendNumber + = 1
self . _ConnectionState = TConnectionState . Login
def sendSystemQuit ( self ) : # code/ryzom/client/src/network_connection.cpp # void CNetworkConnection::sendSystemQuit()
# Disconnect
if self . _sock is None :
raise ValueError
self . _QuitId + = 1
2019-05-31 17:25:04 +00:00
msgout = BitStream ( )
self . buildSystemHeader ( msgout )
msgout . pushUint8 ( CLFECOMMON . SYSTEM_QUIT_CODE )
msgout . pushSint32 ( self . _QuitId ) # _QuitId
self . _sock . sendto ( msgout . toBytes ( ) , self . frontend )
2019-05-19 13:23:03 +00:00
self . _ConnectionState = TConnectionState . Quit
2019-05-30 17:19:54 +00:00
def sendSystemAckSync ( self ) : # code/ryzom/client/src/network_connection.cpp # void CNetworkConnection::sendSystemAckSync()
2019-06-12 21:14:56 +00:00
self . log . debug ( " sendSystemAckSync _LastReceivedNumber: %d _LastAckInLongAck: %d _LatestSync: %d " % ( self . _LastReceivedNumber , self . _LastAckInLongAck , self . _LatestSync ) )
2019-05-31 17:25:04 +00:00
msgout = BitStream ( )
self . buildSystemHeader ( msgout )
msgout . pushUint8 ( CLFECOMMON . SYSTEM_ACK_SYNC_CODE )
msgout . pushSint32 ( self . _LastReceivedNumber )
msgout . pushSint32 ( self . _LastAckInLongAck )
self . _LongAckBitField . writeSerial ( msgout ) # Signale le nombre de packet perdu
msgout . pushSint32 ( self . _LatestSync )
2019-06-12 21:14:56 +00:00
2019-05-31 17:25:04 +00:00
self . _sock . sendto ( msgout . toBytes ( ) , self . frontend )
2019-06-12 21:14:56 +00:00
2019-05-31 17:25:04 +00:00
self . _LatestSyncTime = self . _UpdateTime
2019-06-12 21:14:56 +00:00
# Only to decode message send
msgout . readSint32 ( ' _CurrentSendNumber ' )
msgout . readBool ( ' systemMode ' )
msgout . readUint8 ( ' SYSTEM_ACK_SYNC_CODE ' )
msgout . readSint32 ( ' _LastReceivedNumber ' )
msgout . readSint32 ( ' _LastAckInLongAck ' )
msgout . readUint8 ( ' currentVersion ' ) # currentVersion = 0
msgout . readUint32 ( ' NumBits ' )
size = msgout . readUint32 ( ' size ' )
for _ in range ( 0 , size ) :
msgout . readUint32 ( ' data ' )
msgout . readSint32 ( ' _LatestSync ' )
self . log . debug ( " sendSystemAckSync : %s " % msgout . showAllData ( ) )
2019-05-31 23:45:35 +00:00
def sendSystemAckProbe ( self ) :
self . log . debug ( " sendSystemAckProbe " )
msgout = BitStream ( )
self . buildSystemHeader ( msgout )
msgout . pushUint8 ( CLFECOMMON . SYSTEM_ACK_PROBE_CODE )
msgout . pushSint32 ( len ( self . _LatestProbes ) )
for data in self . _LatestProbes :
msgout . pushSint32 ( data )
self . _LatestProbes = [ ]
self . _sock . sendto ( msgout . toBytes ( ) , self . frontend )
2019-05-31 17:25:04 +00:00
def sendSystemDisconnection ( self ) :
2019-06-06 20:21:35 +00:00
self . log . debug ( " sendSystemDisconnection " )
2019-05-31 17:25:04 +00:00
if self . _sock is None :
raise ValueError
msgout = BitStream ( )
self . buildSystemHeader ( msgout )
msgout . pushUint8 ( CLFECOMMON . SYSTEM_DISCONNECTION_CODE )
self . _sock . sendto ( msgout . toBytes ( ) , self . frontend )
2019-05-30 17:19:54 +00:00
2019-06-06 20:21:35 +00:00
def sendNormalMessage ( self ) :
self . log . debug ( " sendNormalMessage " )
if self . _sock is None :
raise ValueError
msgout = BitStream ( )
msgout . pushSint32 ( self . _CurrentSendNumber )
msgout . pushBool ( False ) # Normal
msgout . pushSint32 ( self . _LastReceivedNumber )
msgout . pushSint32 ( self . _AckBitMask )
numPacked = 0
for block in self . _Actions :
if block . Cycle == 0 :
break
if block . FirstPacket == 0 :
block . FirstPacket = self . _CurrentSendNumber ;
block . serial ( message )
numPacked + = 1
if message . getPosInBit ( ) > 480 * 8 : # easy version
break
self . _sock . sendto ( msgout . toBytes ( ) , self . frontend )
self . _LastSendTime = int ( time . clock_gettime ( 1 ) * 1000 )
self . _PacketStamps . append ( TStampQueue ( self . _CurrentSendNumber , self . _UpdateTime ) )
self . _CurrentSendNumber + = 1
2019-05-19 14:10:18 +00:00
def readDelta ( self , msg ) :
2019-06-05 21:10:20 +00:00
propertyCount = msg . readUint16 ( ' propertyCount ' )
2019-05-19 14:10:18 +00:00
self . log . debug ( " propertyCount: %d " % propertyCount )
2019-06-05 21:10:20 +00:00
self . log . debug ( " TODO " )
2019-05-19 14:10:18 +00:00
for _ in range ( 0 , propertyCount ) :
pass
2019-05-30 17:19:54 +00:00
def buildStream ( self , buffersize = 65536 ) :
2019-05-31 17:25:04 +00:00
# khanat-opennel-code/code/ryzom/client/src/network_connection.cpp # bool CNetworkConnection::buildStream( CBitMemStream &msgin )
2019-05-30 17:19:54 +00:00
data , addr = self . _sock . recvfrom ( buffersize )
return data , addr
def decodeHeader ( self , msg ) :
2019-06-12 21:14:56 +00:00
'''
khanat - opennel - code / code / ryzom / client / src / network_connection . cpp # bool CNetworkConnection::decodeHeader(CBitMemStream &msgin, bool checkMessageNumber)
'''
2019-05-30 21:46:07 +00:00
self . _TotalMessages + = 1
self . _LastReceivedTime = self . _UpdateTime
2019-06-05 21:10:20 +00:00
self . _CurrentReceivedNumber = msg . readSint32 ( ' CurrentReceivedNumber ' )
self . _SystemMode = msg . readBool ( ' SystemMode ' )
2019-05-30 21:46:07 +00:00
if self . checkMessageNumber and self . _CurrentReceivedNumber > self . _LastReceivedPacketInBothModes :
self . _TotalLostPackets + = self . _CurrentReceivedNumber - self . _LastReceivedPacketInBothModes - 1
self . _LastReceivedPacketInBothModes = self . _CurrentReceivedNumber
2019-06-04 19:19:06 +00:00
# else:
# self._LastReceivedPacketInBothModes = self._CurrentReceivedNumber - 1
2019-05-30 21:46:07 +00:00
if not self . _SystemMode :
2019-06-05 21:10:20 +00:00
self . _LastReceivedAck = msg . readSint32 ( ' LastReceivedAck ' ) ;
2019-06-04 19:19:06 +00:00
self . log . debug ( " Normal Mode _LastReceivedAck: %d " % self . _LastReceivedAck )
2019-05-31 17:25:04 +00:00
else :
self . log . debug ( " System Mode " )
2019-05-30 21:46:07 +00:00
if self . _CurrentReceivedNumber > self . _LastReceivedNumber + 1 :
self . log . debug ( " lost messages server->client [ %d ; %d ] " % ( self . _LastReceivedPacketInBothModes + 1 , self . _CurrentReceivedNumber - 1 ) )
elif self . _CurrentReceivedNumber == self . _LastReceivedNumber :
self . log . debug ( " awaiting packet %d , received packet %d " % ( self . _LastReceivedPacketInBothModes + 1 , self . _CurrentReceivedNumber ) )
return False
elif self . _CurrentReceivedNumber < self . _LastReceivedNumber :
self . log . debug ( " received an old message, awaiting packet %d , received packet %d " % ( self . _LastReceivedPacketInBothModes + 1 , self . _CurrentReceivedNumber ) )
return false
ackBool = ( not self . _SystemMode ) and ( self . _ConnectionState == TConnectionState . Connected or self . _ConnectionState == TConnectionState . Synchronize )
if ackBool :
ackBit = 1
else :
ackBit = 0
if self . _CurrentReceivedNumber - self . _LastReceivedNumber < 32 :
2019-06-12 21:14:56 +00:00
self . _AckBitMask << = self . _CurrentReceivedNumber - self . _LastReceivedNumber
self . _AckBitMask | = self . _LastAckBit << ( self . _CurrentReceivedNumber - self . _LastReceivedNumber - 1 )
2019-05-30 21:46:07 +00:00
elif ( self_CurrentReceivedNumber - self_LastReceivedNumber ) == 32 and self . _LastAckBit != 0 :
self . _AckBitMask = 0x80000000
else :
self . _AckBitMask = 0x00000000
self . _LastAckBit = ackBit ;
2019-06-12 21:14:56 +00:00
for i in range ( self . _LastReceivedNumber + 1 , self . _CurrentReceivedNumber ) :
2019-06-02 13:45:55 +00:00
self . _LongAckBitField . clearBit ( i & 511 ) # (512 - 1) mask 9bit
self . _LongAckBitField . set ( self . _CurrentReceivedNumber & 511 , ackBool ) # (512 - 1) mask 9bit
2019-05-31 17:25:04 +00:00
2019-06-12 21:14:56 +00:00
self . log . debug ( " _LastAckInLongAck: %d _CurrentReceivedNumber: %d " % ( self . _LastAckInLongAck , self . _CurrentReceivedNumber ) )
2019-05-31 17:25:04 +00:00
if self . _LastAckInLongAck < = ( self . _CurrentReceivedNumber - 512 ) :
2019-06-02 13:45:55 +00:00
self . _LastAckInLongAck = self . _CurrentReceivedNumber - 511 ; # (512 - 1) mask 9bit
2019-05-31 17:25:04 +00:00
2019-05-30 17:19:54 +00:00
self . _LastReceivedNumber = self . _CurrentReceivedNumber
2019-05-31 17:25:04 +00:00
self . log . debug ( " _CurrentReceivedNumber: %d , _LastReceivedNumber: %d , ackBit: %d , _AckBitMask: %d _LongAckBitField: %s " % ( self . _CurrentReceivedNumber , self . _LastReceivedNumber , ackBit , self . _AckBitMask , self . _LongAckBitField ) )
2019-05-30 21:46:07 +00:00
return True
2019-05-30 17:19:54 +00:00
def receiveSystemProbe ( self , msg ) :
2019-05-31 23:45:35 +00:00
self . _LatestProbeTime = self . _UpdateTime
2019-06-05 21:10:20 +00:00
self . _LatestProbe = msg . readSint32 ( ' LatestProbe ' )
2019-05-30 17:19:54 +00:00
self . log . debug ( " LatestProbe: %d " % self . _LatestProbe )
2019-05-31 23:45:35 +00:00
self . _LatestProbes . append ( self . _LatestProbe )
2019-05-30 17:19:54 +00:00
def receiveSystemStalled ( self , msg ) :
self . log . debug ( " received STALLED " )
def receiveSystemSync ( self , msg ) :
2019-05-31 17:25:04 +00:00
self . _LatestSyncTime = self . _UpdateTime
2019-06-05 21:10:20 +00:00
self . _Synchronize = msg . readUint32 ( ' Synchronize ' )
stime = msg . readSint64 ( ' stime ' )
self . _LatestSync = msg . readUint32 ( ' LatestSync ' )
2019-05-30 21:46:07 +00:00
self . log . debug ( " %d %d %d " % ( self . _Synchronize , stime , self . _LatestSync ) )
2019-05-30 17:19:54 +00:00
# khanat-opennel-code/code/ryzom/client/src/network_connection.cpp : void CNetworkConnection::receiveSystemSync(CBitMemStream &msgin)
2019-06-05 21:10:20 +00:00
MsgData = msg . readArrayUint8 ( 16 , ' MsgData ' )
DatabaseData = msg . readArrayUint8 ( 16 , ' DatabaseData ' )
2019-05-30 17:19:54 +00:00
self . log . debug ( " MsgData: " + str ( MsgData ) )
self . log . debug ( " DatabaseData: " + str ( DatabaseData ) )
2019-05-30 18:40:42 +00:00
md5Msg = bytes ( MsgData )
md5Database = bytes ( DatabaseData )
if md5Msg == self . _MsgXmlMD5 :
self . log . info ( " Check MD5 msg.xml : OK " )
else :
self . log . error ( " Check MD5 msg.xml : KO " )
if md5Database == self . _DatabaseXmlMD5 :
self . log . info ( " Check MD5 database.xml : OK " )
else :
self . log . error ( " Check MD5 database.xml : KO " )
2019-05-30 21:46:07 +00:00
self . _MsPerTick = 100
self . _CurrentServerTick = self . _Synchronize + self . _CurrentReceivedNumber + 2
self . _CurrentClientTick = self . _CurrentServerTick - ( self . _LCT + self . _MsPerTick ) / self . _MsPerTick
self . _CurrentClientTime = self . _UpdateTime - ( self . _LCT + self . _MsPerTick )
self . sendSystemAckSync ( )
2019-05-30 17:19:54 +00:00
2019-06-02 13:45:55 +00:00
def decodeVisualProperties ( self , msgin ) :
2019-06-06 20:21:35 +00:00
'''
2019-06-12 21:14:56 +00:00
khanat - opennel - code / code / ryzom / client / src / network_connection . cpp # void CNetworkConnection::decodeVisualProperties( CBitMemStream& msgin )
2019-06-06 20:21:35 +00:00
'''
while True :
if msgin . getPosInBit ( ) + 8 * 8 > len ( msgin ) * 8 :
return
slot = msgin . readUint8 ( ' slot ' )
associationBits = msgin . readUint32 ( ' associationBits ' )
self . log . debug ( " TODO " )
return
2019-06-02 13:45:55 +00:00
2019-05-31 17:25:04 +00:00
def receiveNormalMessage ( self , msgin ) :
2019-06-02 13:45:55 +00:00
self . log . debug ( " received normal message Packet ( %d ) %s " % ( msgin . needRead ( ) , msgin . showLastData ( ) ) )
actions = self . _ImpulseDecoder . decode ( msgin , self . _CurrentReceivedNumber , self . _LastReceivedAck , self . _CurrentSendNumber )
if actions :
self . log . debug ( ' actions: ' + ' , ' . join ( [ str ( x ) for x in actions ] ) )
else :
self . log . debug ( ' actions: None ' )
self . log . debug ( " Message not read ( %d ) %s " % ( msgin . needRead ( ) , msgin . showLastData ( ) ) )
2019-06-06 20:21:35 +00:00
# remove all old actions that are acked
2019-06-02 13:45:55 +00:00
while self . _Actions and self . _Actions [ 0 ] . FirstPacket != 0 and self . _Actions [ 0 ] . FirstPacket :
2019-06-06 20:21:35 +00:00
self . log . debug ( " remove old action " )
2019-06-02 13:45:55 +00:00
self . _Actions . pop ( 0 )
self . _CurrentServerTick = self . _CurrentReceivedNumber * 2 + self . _Synchronize
2019-06-06 20:21:35 +00:00
# remove useless stamps in queue
while len ( self . _PacketStamps ) != 0 and self . _LastReceivedAck > self . _PacketStamps [ 0 ] . first :
self . _PacketStamps . pop ( 0 )
# Statistique !
if len ( self . _PacketStamps ) == 0 or self . _PacketStamps [ 0 ] . first > self . _LastReceivedAck :
pass
else :
ackedPacketTime = self . _PacketStamps [ 0 ] . second
ping = self . _UpdateTime - ackedPacketTime
self . _InstantPing = ping
if ping < self . _BestPing :
self . _BestPing = ping
earliest = ackedPacketTime + self . _BestPing / / 2
latest = self . _UpdateTime - self . _BestPing / / 2
numStepTick = self . _CurrentServerTick - self . _CurrentClientTick
if numStepTick > 0 and earliest > self . _CurrentClientTime and latest > self . _CurrentClientTime :
if self . _CurrentClientTime + self . _MsPerTick * numStepTick < earliest :
self . _MsPerTick = ( earliest - self . _CurrentClientTime ) / / numStepTick
if ( self . _CurrentClientTime + self . _MsPerTick * numStepTick ) > latest :
self . _MsPerTick = ( latest - self . _CurrentClientTime ) / / numStepTick
if self . _MsPerTick == 0 :
self . log . warning ( " _MsPerTick is 0 because server tick is too big %d compare to the client tick is %d " % ( self . _CurrentServerTick , self . _CurrentClientTick ) )
self . _MsPerTick = 1
elif numStepTick < = 0 :
self . _MsPerTick = self . _LCT
2019-06-02 13:45:55 +00:00
## remove useless stamps in queue
#while self._PacketStamps and self._LastReceivedAck > self._PacketStamps[0].first:
# self._PacketStamps.pop(0)
# Decode the actions received in the impulsions
for action in actions :
if action . Code == TActionCode . ACTION_DISCONNECTION_CODE :
self . log . debug ( " Action : ACTION_DISCONNECTION_CODE " )
self . disconnect ( )
elif action . Code == TActionCode . ACTION_GENERIC_CODE :
self . log . debug ( " Action : ACTION_GENERIC_CODE " )
action . genericAction ( self . decodeImpulse )
elif action . Code == TActionCode . ACTION_GENERIC_MULTI_PART_CODE :
self . log . debug ( " Action : ACTION_GENERIC_MULTI_PART_CODE " )
action . genericAction ( self . decodeImpulse )
elif action . Code == TActionCode . ACTION_DUMMY_CODE :
self . log . debug ( " Action : ACTION_DUMMY_CODE " )
self . _ImpulseDecoder . removeCAction ( action )
# Decode the visual properties
self . decodeVisualProperties ( msgin ) ;
2019-06-06 20:21:35 +00:00
self . _LastReceivedNormalTime = int ( time . clock_gettime ( 1 ) * 1000 )
2019-05-31 17:25:04 +00:00
2019-05-31 23:45:35 +00:00
def receiveSystemAckQuit ( self , msgin ) :
self . log . debug ( " received ACK_QUIT " )
self . _ReceivedAckQuit = True
2019-05-30 17:19:54 +00:00
def disconnect ( self ) :
2019-05-31 17:25:04 +00:00
self . log . info ( " Disconnect " )
self . sendSystemDisconnection ( )
self . _sock . close ( )
selc . _sock = None
self . _ConnectionState = TConnectionState . Disconnect
def stateLogin ( self , msgin ) :
self . decodeHeader ( msgin )
if self . _SystemMode :
2019-06-05 21:10:20 +00:00
message = msgin . readUint8 ( ' message ' )
2019-05-31 17:25:04 +00:00
self . log . debug ( " _CurrentReceivedNumber: %d (mode: %s ) %d [ %d / %d / %d ] " % ( self . _CurrentReceivedNumber , str ( self . _SystemMode ) , message , msgin . sizeData ( ) , msgin . sizeRead ( ) , msgin . needRead ( ) ) )
if message == CLFECOMMON . SYSTEM_SYNC_CODE :
self . _ConnectionState = TConnectionState . Synchronize
self . log . debug ( " Login->synchronize " )
self . receiveSystemSync ( msgin )
return True
elif message == CLFECOMMON . SYSTEM_STALLED_CODE :
self . log . debug ( " received STALLED " )
self . _ConnectionState = TConnectionState . Stalled
self . receiveSystemStalled ( msgin )
return True
elif message == CLFECOMMON . SYSTEM_PROBE_CODE :
self . log . debug ( " Login->probe " )
self . _ConnectionState = TConnectionState . Probe
self . receiveSystemProbe ( msgin )
return True
elif message == CLFECOMMON . SYSTEM_SERVER_DOWN_CODE :
self . disconnect ( )
self . log . warning ( " BACK-END DOWN " )
return False
else :
self . log . warning ( " CNET: received system %d in state Login " % message )
self . log . debug ( " _CurrentReceivedNumber: %d (mode: %s ) %d [ %d / %d / %d ] ' %s ' " % ( self . _CurrentReceivedNumber , str ( self . _SystemMode ) , message , msgin . sizeData ( ) , msgin . sizeRead ( ) , msgin . needRead ( ) , msgin . showLastData ( ) ) )
else :
self . log . warning ( " CNET: received normal in state Login " )
return False
def stateSynchronize ( self , msgin ) :
self . decodeHeader ( msgin )
if self . _SystemMode :
2019-06-05 21:10:20 +00:00
message = msgin . readUint8 ( ' message ' )
2019-05-31 17:25:04 +00:00
self . log . debug ( " _CurrentReceivedNumber: %d (mode: %s ) %d [ %d / %d / %d ] " % ( self . _CurrentReceivedNumber , str ( self . _SystemMode ) , message , msgin . sizeData ( ) , msgin . sizeRead ( ) , msgin . needRead ( ) ) )
if message == CLFECOMMON . SYSTEM_PROBE_CODE :
self . log . debug ( " synchronize->probe " )
self . _ConnectionState = TConnectionState . Probe
self . receiveSystemProbe ( msgin )
return True
elif message == CLFECOMMON . SYSTEM_STALLED_CODE :
self . log . debug ( " received STALLED " )
self . _ConnectionState = TConnectionState . Stalled
self . receiveSystemStalled ( msgin )
return True
elif message == CLFECOMMON . SYSTEM_SYNC_CODE :
self . log . debug ( " synchronize->synchronize " )
self . receiveSystemSync ( msgin )
elif message == CLFECOMMON . SYSTEM_SERVER_DOWN_CODE :
self . disconnect ( )
self . log . warning ( " BACK-END DOWN " )
return False
else :
self . log . warning ( " CNET: received system %d in state Synchronize " % message )
self . log . debug ( " _CurrentReceivedNumber: %d (mode: %s ) %d [ %d / %d / %d ] ' %s ' " % ( self . _CurrentReceivedNumber , str ( self . _SystemMode ) , message , msgin . sizeData ( ) , msgin . sizeRead ( ) , msgin . needRead ( ) , msgin . showLastData ( ) ) )
else :
self . _ConnectionState = TConnectionState . Connected
self . log . warning ( " CNET: synchronize->connected " )
# _Changes.push_back(CChange(0, ConnectionReady));
2019-06-12 21:14:56 +00:00
self . _ImpulseDecoder . reset ( ) ;
2019-05-31 17:25:04 +00:00
self . receiveNormalMessage ( msgin ) ;
return True
2019-06-12 21:14:56 +00:00
self . log . debug ( " sendSystemAckSync ? ( %d , %d , %d ) " % ( self . _UpdateTime , self . _LatestSyncTime , self . _UpdateTime - self . _LatestSyncTime ) )
2019-05-31 17:25:04 +00:00
if self . _UpdateTime - self . _LatestSyncTime > 300 :
self . sendSystemAckSync ( ) ;
return False
def stateConnected ( self , msgin ) :
self . decodeHeader ( msgin )
if self . _SystemMode :
2019-06-05 21:10:20 +00:00
message = msgin . readUint8 ( ' message ' )
2019-05-31 17:25:04 +00:00
self . log . debug ( " _CurrentReceivedNumber: %d (mode: %s ) %d [ %d / %d / %d ] " % ( self . _CurrentReceivedNumber , str ( self . _SystemMode ) , message , msgin . sizeData ( ) , msgin . sizeRead ( ) , msgin . needRead ( ) ) )
if message == CLFECOMMON . SYSTEM_PROBE_CODE :
self . log . debug ( " Connected->probe " )
self . _ConnectionState = TConnectionState . Probe
self . receiveSystemProbe ( msgin )
return True
elif message == CLFECOMMON . SYSTEM_SYNC_CODE :
self . log . debug ( " Connected->synchronize " )
self . receiveSystemSync ( msgin )
return True
elif message == CLFECOMMON . SYSTEM_STALLED_CODE :
self . log . debug ( " received STALLED " )
self . _ConnectionState = TConnectionState . Stalled
self . receiveSystemStalled ( msgin )
return True
elif message == CLFECOMMON . SYSTEM_SERVER_DOWN_CODE :
self . disconnect ( )
self . log . warning ( " BACK-END DOWN " )
return False
else :
self . log . warning ( " CNET: received system %d in state Connected " % message )
self . log . debug ( " _CurrentReceivedNumber: %d (mode: %s ) %d [ %d / %d / %d ] ' %s ' " % ( self . _CurrentReceivedNumber , str ( self . _SystemMode ) , message , msgin . sizeData ( ) , msgin . sizeRead ( ) , msgin . needRead ( ) , msgin . showLastData ( ) ) )
else :
self . receiveNormalMessage ( msgin ) ;
return True
return False
2019-05-30 17:19:54 +00:00
2019-05-31 23:45:35 +00:00
def stateProbe ( self , msgin ) :
self . decodeHeader ( msgin )
if self . _SystemMode :
2019-06-05 21:10:20 +00:00
message = msgin . readUint8 ( ' message ' )
2019-05-31 23:45:35 +00:00
self . log . debug ( " _CurrentReceivedNumber: %d (mode: %s ) %d [ %d / %d / %d ] " % ( self . _CurrentReceivedNumber , str ( self . _SystemMode ) , message , msgin . sizeData ( ) , msgin . sizeRead ( ) , msgin . needRead ( ) ) )
if message == CLFECOMMON . SYSTEM_SYNC_CODE :
self . log . debug ( " probe->synchronize " )
self . _ConnectionState = TConnectionState . Synchronize
self . receiveSystemSync ( msgin )
return True
elif message == CLFECOMMON . SYSTEM_STALLED_CODE :
self . log . debug ( " probe->stalled " )
self . _ConnectionState = TConnectionState . Stalled
self . receiveSystemStalled ( msgin )
return True
elif message == CLFECOMMON . SYSTEM_PROBE_CODE :
self . receiveSystemProbe ( msgin )
elif message == CLFECOMMON . SYSTEM_SERVER_DOWN_CODE :
self . disconnect ( )
self . log . warning ( " BACK-END DOWN " )
return False
else :
self . log . warning ( " CNET: received system %d in state Probe " % message )
self . log . debug ( " _CurrentReceivedNumber: %d (mode: %s ) %d [ %d / %d / %d ] ' %s ' " % ( self . _CurrentReceivedNumber , str ( self . _SystemMode ) , message , msgin . sizeData ( ) , msgin . sizeRead ( ) , msgin . needRead ( ) , msgin . showLastData ( ) ) )
else :
self . log . warning ( " received normal in state Probe " )
if ( len ( self . _LatestProbes ) > 0 ) or ( self . _UpdateTime - self . _LatestProbeTime > 300 ) :
self . sendSystemAckProbe ( )
self . _LatestProbeTime = self . _UpdateTime
return False
def stateStalled ( self , msgin ) :
self . decodeHeader ( msgin )
if self . _SystemMode :
2019-06-05 21:10:20 +00:00
message = msgin . readUint8 ( ' message ' )
2019-05-31 23:45:35 +00:00
self . log . debug ( " _CurrentReceivedNumber: %d (mode: %s ) %d [ %d / %d / %d ] " % ( self . _CurrentReceivedNumber , str ( self . _SystemMode ) , message , msgin . sizeData ( ) , msgin . sizeRead ( ) , msgin . needRead ( ) ) )
if message == CLFECOMMON . SYSTEM_SYNC_CODE :
self . log . debug ( " stalled->synchronize " )
self . _ConnectionState = TConnectionState . Synchronize
self . receiveSystemSync ( msgin )
return True
elif message == CLFECOMMON . SYSTEM_PROBE_CODE :
self . log . debug ( " stalled->probe " )
self . _ConnectionState = TConnectionState . Probe
self . receiveSystemProbe ( msgin )
elif message == CLFECOMMON . SYSTEM_STALLED_CODE :
self . receiveSystemStalled ( msgin )
elif message == CLFECOMMON . SYSTEM_SERVER_DOWN_CODE :
self . disconnect ( )
self . log . warning ( " BACK-END DOWN " )
return False
else :
self . log . warning ( " CNET: received system %d in state Stalled " % message )
self . log . debug ( " _CurrentReceivedNumber: %d (mode: %s ) %d [ %d / %d / %d ] ' %s ' " % ( self . _CurrentReceivedNumber , str ( self . _SystemMode ) , message , msgin . sizeData ( ) , msgin . sizeRead ( ) , msgin . needRead ( ) , msgin . showLastData ( ) ) )
else :
self . log . warning ( " received normal in state Stalled " )
return False
def stateQuit ( self , msgin ) :
self . decodeHeader ( msgin )
if self . _SystemMode :
2019-06-05 21:10:20 +00:00
message = msgin . readUint8 ( ' message ' )
2019-05-31 23:45:35 +00:00
self . log . debug ( " _CurrentReceivedNumber: %d (mode: %s ) %d [ %d / %d / %d ] " % ( self . _CurrentReceivedNumber , str ( self . _SystemMode ) , message , msgin . sizeData ( ) , msgin . sizeRead ( ) , msgin . needRead ( ) ) )
if message == CLFECOMMON . SYSTEM_SYNC_CODE :
self . log . debug ( " quit->synchronize " )
self . _ConnectionState = TConnectionState . Synchronize
self . receiveSystemSync ( msgin )
return True
elif message == CLFECOMMON . SYSTEM_SERVER_DOWN_CODE :
self . disconnect ( )
self . log . warning ( " BACK-END DOWN " )
return False
elif message == CLFECOMMON . SYSTEM_ACK_QUIT_CODE :
self . receiveSystemAckQuit ( msgin )
else :
self . log . warning ( " CNET: received system %d in state Quit " % message )
self . log . debug ( " _CurrentReceivedNumber: %d (mode: %s ) %d [ %d / %d / %d ] ' %s ' " % ( self . _CurrentReceivedNumber , str ( self . _SystemMode ) , message , msgin . sizeData ( ) , msgin . sizeRead ( ) , msgin . needRead ( ) , msgin . showLastData ( ) ) )
else :
self . log . warning ( " received normal in state Quit " )
if not self . _ReceivedAckQuit and ( self . _UpdateTime - self . _LatestQuitTime > 100 ) :
self . sendSystemQuit ( )
self . _LatestQuitTime = self . _UpdateTime
return False
2019-05-30 21:46:07 +00:00
def update ( self ) :
# khanat-opennel-code/code/ryzom/client/src/network_connection.cpp # bool CNetworkConnection::update()
self . _UpdateTime = int ( time . clock_gettime ( 1 ) * 1000 )
self . _ReceivedSync = False
2019-05-31 17:25:04 +00:00
if not self . _sock :
return False
2019-05-31 23:45:35 +00:00
# TODO - REMOVE this counter (just to stop loop)
counterLoop = 0
2019-05-31 17:25:04 +00:00
stateBroke = True
while stateBroke :
buffer , addr = self . buildStream ( )
msgin = BitStream ( )
msgin . fromBytes ( buffer )
2019-06-04 19:19:06 +00:00
self . log . debug ( " received message: %s " % msgin . showAllData ( ) )
2019-05-31 17:25:04 +00:00
if self . _ConnectionState == TConnectionState . Login :
self . log . debug ( " state:Login " )
stateBroke = self . stateLogin ( msgin )
elif self . _ConnectionState == TConnectionState . Synchronize :
self . log . debug ( " state:Synchronize " )
stateBroke = self . stateSynchronize ( msgin )
elif self . _ConnectionState == TConnectionState . Connected :
self . log . debug ( " state:Connected " )
stateBroke = self . stateConnected ( msgin )
elif self . _ConnectionState == TConnectionState . Probe :
self . log . debug ( " state:Probe " )
2019-05-31 23:45:35 +00:00
stateBroke = self . stateProbe ( msgin )
2019-05-31 17:25:04 +00:00
elif self . _ConnectionState == TConnectionState . Stalled :
self . log . debug ( " state:Stalled " )
2019-05-31 23:45:35 +00:00
stateBroke = self . stateStalled ( msgin )
2019-05-31 17:25:04 +00:00
elif self . _ConnectionState == TConnectionState . Quit :
self . log . debug ( " state:Quit " )
2019-05-31 23:45:35 +00:00
stateBroke = self . stateQuit ( msgin )
2019-05-31 17:25:04 +00:00
else :
stateBroke = False
2019-06-04 19:19:06 +00:00
self . log . debug ( " message decoded: %s " % msgin . showAllData ( ) )
2019-05-31 23:45:35 +00:00
counterLoop + = 1
if counterLoop > 10 :
break
2019-05-31 17:25:04 +00:00
2019-06-06 20:21:35 +00:00
def send ( self ) :
if self . _ConnectionState == TConnectionState . Connected and self . _LastSendTime > 100 :
self . sendNormalMessage ( )
2019-05-30 17:37:42 +00:00
def EmulateFirst ( self , msgRawXml , databaseRawXml ) :
2019-05-30 18:40:42 +00:00
self . msgXml = ET . fromstring ( msgRawXml )
#ET.dump(msgXml)
self . databaseXml = ET . fromstring ( databaseRawXml )
#ET.dump(databaseXml)
2019-05-30 17:37:42 +00:00
self . _MsgXmlMD5 = getTextMD5 ( msgRawXml )
self . _DatabaseXmlMD5 = getTextMD5 ( databaseRawXml )
2019-06-02 13:45:55 +00:00
self . decodeImpulse . loadMsg ( self . msgXml )
self . decodeImpulse . loadDatabase ( self . databaseXml )
2019-05-31 17:25:04 +00:00
self . connect ( )
2019-05-19 14:10:18 +00:00
self . log . info ( " Client Login " )
2019-05-19 13:23:03 +00:00
self . sendSystemLogin ( )
2019-05-19 14:10:18 +00:00
self . log . info ( " Receive Message " )
2019-06-06 20:21:35 +00:00
i = 0
for _ in range ( 0 , 50 ) :
#while True:
self . log . debug ( " %s [ %s : %d ] %s " % ( " * " * 40 , " Loop " , i , " * " * 40 ) )
2019-05-30 21:46:07 +00:00
self . update ( )
2019-06-06 20:21:35 +00:00
self . send ( )
i + = 1
2019-05-19 14:10:18 +00:00
2019-05-31 17:25:04 +00:00
self . log . info ( " Client Quit " )
2019-05-19 13:23:03 +00:00
self . sendSystemQuit ( )
class ClientKhanat :
def __init__ ( self ,
2019-05-30 17:19:54 +00:00
khanat_host ,
khanat_port_login = 40916 ,
khanat_port_frontend = 47851 ,
2019-05-19 13:23:03 +00:00
login = " tester " ,
password = " tester " ,
clientApp = " Lirria " ,
LanguageCode = " fr " ,
url = " /login/r2_login.php " ,
2019-05-19 13:29:43 +00:00
suffix = None ,
2019-05-19 14:10:18 +00:00
download_patch = False ,
2019-05-30 17:19:54 +00:00
show_patch_detail = False ,
size_buffer_file = 1024 ) :
2019-05-19 13:23:03 +00:00
self . log = logging . getLogger ( ' myLogger ' )
if suffix is None :
suffix = str ( random . randrange ( 1 , 9999 ) )
self . log . debug ( " suffix : %s " % suffix )
2019-05-19 13:29:43 +00:00
self . download_patch = download_patch
2019-05-19 14:10:18 +00:00
self . show_patch_detail = show_patch_detail
2019-05-30 17:19:54 +00:00
self . khanat_host = khanat_host
self . khanat_port_login = khanat_port_login
self . khanat_port_frontend = khanat_port_frontend
2019-05-19 13:23:03 +00:00
self . login = login + suffix
self . password = password
self . clientApp = clientApp
self . LanguageCode = LanguageCode
self . url = url
self . cookie , self . fsaddr , self . ringmainurl , self . fartp , self . stat , self . r2serverversion , self . r2backuppatchurl , self . r2patchurl = None , None , None , None , None , None , None , None
self . tempdir = tempfile . TemporaryDirectory ( " .khanat " )
self . log . debug ( " Temporary directory: %s " % self . tempdir )
self . khanat_idx = CPersistentDataRecord ( self . log )
self . UserAddr , self . UserKey , self . UserId = None , None , None
2019-05-30 17:19:54 +00:00
self . clientNetworkConnection = ClientNetworkConnection ( self . khanat_host , self . khanat_port_frontend )
self . size_buffer_file = size_buffer_file
self . cFileContainer = CFileContainer ( )
2019-05-19 13:23:03 +00:00
def createAccount ( self ) :
2019-05-30 17:19:54 +00:00
conn = http . client . HTTPConnection ( host = self . khanat_host , port = self . khanat_port_login )
2019-05-19 13:23:03 +00:00
cmd = " /ams/index.php?page=register "
headers = { ' Accept ' : ' text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 ' ,
' Accept-Language ' : ' en-US ' ,
' Connection ' : ' keep-alive ' ,
' DNT ' : ' 1 ' ,
' Cookie ' : ' PHPSESSID=lsoumn9f0ljgm3vo3hgjdead03 ' ,
2019-05-30 17:19:54 +00:00
' Host ' : self . khanat_host + ' : ' + str ( self . khanat_port_login ) ,
' Referer ' : ' http:// ' + self . khanat_host + ' : ' + str ( self . khanat_port_login ) + ' /ams/index.php?page=register ' ,
2019-05-19 13:23:03 +00:00
' Upgrade-Insecure-Requests ' : ' 1 ' ,
' User-Agent ' : ' Mozilla/5.0 (Windows NT 6.1; rv:6.0) Gecko/20100101 Firefox/6.0 ' ,
' Content-Type ' : ' application/x-www-form-urlencoded ' }
headers = { ' Content-Type ' : ' application/x-www-form-urlencoded ' }
params = urllib . parse . urlencode ( { ' Username ' : self . login , ' Password ' : self . password , ' ConfirmPass ' : self . password , ' Email ' : self . login + ' @khaganat.net ' , ' TaC ' : ' on ' , ' function ' : ' add_user ' } )
conn . request ( " POST " , cmd , params , headers )
response = conn . getresponse ( )
if ( int ( response . status ) == 302 ) :
conn . close ( )
self . log . info ( " Account : %s " % self . login )
return
elif ( int ( response . status ) != 200 ) :
self . log . error ( " Impossible to create account (return code: " + str ( response . status ) + " ) " )
sys . exit ( 2 )
ret = response . read ( )
conn . close ( )
ret2 = ret . decode ( )
try :
state , comment = ret2 . split ( " : " , 2 )
except :
state = 1
comment = " "
if int ( state ) != 1 :
self . log . error ( " Impossible to create account (state: " + state + " , comment: " + comment . strip ( ) + " ) " )
sys . exit ( 2 )
errordetected = False
for line in ret2 . split ( ' \n ' ) :
m = re . search ( " (<strong>(?P<type>.*) Error</strong> )(?P<comment>[^.]+) " , line )
if m :
if m . group ( ' comment ' ) == ' Username ' + self . login + ' is in use ' :
continue
if m . group ( ' comment ' ) == ' Email is in use ' :
continue
self . log . error ( ' Impossible to create account: field: %s ( %s ) ' % ( m . group ( ' type ' ) , m . group ( ' comment ' ) ) )
errordetected = True
if errordetected :
sys . exit ( 2 )
self . log . info ( " Reuse account : %s " % self . login )
def connectR2 ( self ) :
2019-05-30 17:19:54 +00:00
conn = http . client . HTTPConnection ( host = self . khanat_host , port = self . khanat_port_login )
2019-05-19 13:23:03 +00:00
cmd = self . url + " ?cmd=ask&cp=2&login= " + self . login + " &lg= " + self . LanguageCode
conn . request ( " GET " , cmd )
response = conn . getresponse ( )
if ( int ( response . status ) != 200 ) :
self . log . error ( " Impossible to get salt (return code: " + str ( response . status ) + " ) " )
sys . exit ( 2 )
ret = response . read ( )
conn . close ( )
try :
state , salt = ret . decode ( ) . split ( " : " , 1 )
except UnicodeDecodeError :
try :
state , salt = ret . decode ( encoding = ' cp1252 ' ) . split ( " : " , 1 )
except UnicodeDecodeError :
self . log . error ( " Impossible to read output login " )
sys . exit ( 2 )
if int ( state ) != 1 :
self . log . error ( " Impossible to get salt (state: " + state + " ) " )
cryptedPassword = crypt . crypt ( self . password , salt )
2019-05-30 17:19:54 +00:00
conn = http . client . HTTPConnection ( host = self . khanat_host , port = self . khanat_port_login )
2019-05-19 13:23:03 +00:00
cmd = self . url + " ?cmd=login&login= " + self . login + " &password= " + cryptedPassword + " &clientApplication= " + self . clientApp + " &cp=2 " + " &lg= " + self . LanguageCode
conn . request ( " GET " , cmd )
response = conn . getresponse ( )
self . log . debug ( " %s %s " % ( response . status , response . reason ) )
ret = response . read ( )
self . log . debug ( ret )
try :
line = ret . decode ( ) . split ( ' \n ' )
except UnicodeDecodeError :
try :
line = ret . decode ( encoding = ' cp1252 ' ) . split ( ' \n ' )
except UnicodeDecodeError :
self . log . error ( " Impossible to read output login " )
sys . exit ( 2 )
self . log . debug ( line [ 0 ] )
self . log . debug ( " line 0 ' %s ' " % line [ 0 ] )
self . log . debug ( " line 1 ' %s ' " % line [ 1 ] )
try :
state , self . cookie , self . fsaddr , self . ringmainurl , self . fartp , self . stat = line [ 0 ] . split ( " # " , 6 )
except :
try :
state , self . cookie , self . fsaddr , self . ringmainurl , self . fartp = line [ 0 ] . split ( " # " , 5 )
self . stat = 0
except :
state , error = line [ 0 ] . split ( " : " , 1 )
if int ( state ) != 1 :
self . log . error ( error )
sys . exit ( 2 )
self . r2serverversion , self . r2backuppatchurl , self . r2patchurl = line [ 1 ] . split ( " # " )
self . log . debug ( " %s %s %s %s %s %s %s %s %s " % ( state , self . cookie , self . fsaddr , self . ringmainurl , self . fartp , self . stat , self . r2serverversion , self . r2backuppatchurl , self . r2patchurl ) )
self . UserAddr , self . UserKey , self . UserId = [ int ( x , 16 ) for x in self . cookie . split ( ' | ' ) ]
conn . close ( )
self . log . info ( " Login Ok " )
self . clientNetworkConnection . cookiesInit ( self . UserAddr , self . UserKey , self . UserId )
def downloadFileUrl ( self , source , dest ) :
self . log . info ( " Download %s (destination: %s ) " % ( source , dest ) )
with urllib . request . urlopen ( source ) as conn :
header = conn . getheaders ( )
file_size = 0
for key , value in header :
if key == ' Content-Length ' :
file_size = int ( value )
break
self . log . debug ( " size: %d " , file_size )
file_size_dl = 0
2019-05-30 17:19:54 +00:00
block_size = self . size_buffer_file # 1024
2019-05-19 13:23:03 +00:00
with open ( dest , ' wb ' ) as fp :
while True :
buffer = conn . read ( block_size )
if not buffer :
break
file_size_dl + = len ( buffer )
fp . write ( buffer )
self . log . debug ( " Download %s %10d [ %6.2f %% ] " % ( source , file_size_dl , file_size_dl * 100. / file_size ) )
fp . close ( )
self . log . debug ( " Downloaded %s ( %d ) " % ( source , file_size ) )
def getServerFile ( self , name , bZipped = False , specifyDestName = None ) :
srcName = name
if specifyDestName :
dstName = specifyDestName
else :
dstName = os . path . basename ( name )
if bZipped :
srcName + = " .ngz "
dstName + = " .ngz "
self . log . info ( " Download %s (destination: %s , zip: %d ) " % ( srcName , dstName , bZipped ) )
dstName = os . path . join ( self . tempdir . name , dstName )
self . downloadFileUrl ( ' http:// ' + self . r2patchurl + ' / ' + srcName , dstName )
return dstName
def downloadAllPatch ( self ) :
2019-05-19 13:29:43 +00:00
# TODO - check where client search file to download
2019-05-19 13:23:03 +00:00
for file in self . khanat_idx . CBNPFile :
tmp = self . getServerFile ( " %05d / %s .lzma " % ( int ( self . r2serverversion ) , file . FileName ) , False , " " )
with lzma . open ( tmp ) as fin :
dstName = os . path . join ( self . tempdir . name , file . FileName )
with open ( dstName , " wb " ) as fout :
data = fin . read ( )
fout . write ( data )
self . log . info ( " %s " % dstName )
2019-05-30 17:19:54 +00:00
os . remove ( tmp )
# khanat-opennel-code/code/ryzom/client/src/login_patch.cpp # void CCheckThread::run ()
FilesToPatch = [ ]
for file in self . khanat_idx . CBNPFile :
FilesToPatch . append ( file )
# Here we got all the files to patch in FilesToPatch and all the versions that must be obtained Now we have to get the optional categories
OptionalCat = [ ]
for category in self . khanat_idx . Categories :
if category . _IsOptional :
for file in category . _Files :
bAdded = False
for file2 in FilesToPatch :
if file2 == file :
OptionalCat . append ( category . _Name )
bAdded = True
break
if bAdded :
break
# For all categories that required an optional category if the cat required is present the category that reference it must be present
for category in self . khanat_idx . Categories :
if category . _IsOptional and not len ( category . _CatRequired ) == 0 :
bFound = False
for cat in OptionalCat :
if category . _Name == cat :
bFound = True
break
if bFound :
for cat in OptionalCat :
if category . _CatRequired == cat :
OptionalCat . append ( category . _Name )
break
# Delete categories optional cat that are hidden
for category in self . khanat_idx . Categories :
if category . _IsOptional and category . _Hidden :
for cat in OptionalCat :
if category . _Name == cat :
OptionalCat . remove ( category . _Name )
break
# Get all extract to category and check files inside the bnp with real files
for category in self . khanat_idx . Categories :
if len ( category . _UnpackTo ) != 0 :
for file in category . _Files :
# TODO
# readHeader()
pass
def DownloadMinimum ( self ) :
self . log . debug ( " - " * 80 )
for file in self . khanat_idx . CBNPFile :
if file . FileName != " kh_server.bnp " :
continue
tmp = self . getServerFile ( " %05d / %s .lzma " % ( int ( self . r2serverversion ) , file . FileName ) , False , " " )
with lzma . open ( tmp ) as fin :
dstName = os . path . join ( self . tempdir . name , file . FileName )
with open ( dstName , " wb " ) as fout :
data = fin . read ( )
fout . write ( data )
self . log . info ( " %s " % dstName )
os . remove ( tmp )
2019-05-19 13:23:03 +00:00
def Emulate ( self ) :
self . createAccount ( )
self . connectR2 ( )
# download patch
self . ryzomidx = self . getServerFile ( " %05d /ryzom_ %05d .idx " % ( int ( self . r2serverversion ) , int ( self . r2serverversion ) ) , False , " " )
self . khanat_idx . readFromBinFile ( self . ryzomidx )
self . khanat_idx . CProductDescriptionForClient_apply ( )
# Show detail patch
2019-05-19 14:10:18 +00:00
if self . show_patch_detail :
self . khanat_idx . decrypt_token ( )
self . khanat_idx . show ( )
2019-05-19 13:23:03 +00:00
# Todo analyze patch and download if necessary or update if incremental - see category
# Download all file in patch - login_patch.cpp:2578 # void CPatchThread::processFile (CPatchManager::SFileToPatch &rFTP)
2019-05-19 13:29:43 +00:00
if self . download_patch :
self . downloadAllPatch ( )
2019-05-30 17:19:54 +00:00
else :
self . DownloadMinimum ( )
self . cFileContainer = CFileContainer ( )
self . cFileContainer . addSearchPath ( self . tempdir . name )
2019-05-30 17:37:42 +00:00
msgRawXml = self . cFileContainer . getdata ( " msg.xml " ) . decode ( )
databaseRawXml = self . cFileContainer . getdata ( " database.xml " ) . decode ( )
self . clientNetworkConnection . EmulateFirst ( msgRawXml , databaseRawXml )
2019-05-19 13:23:03 +00:00
def main ( ) :
FORMAT = ' %(asctime)-15s %(levelname)s %(filename)s : %(lineno)d %(message)s '
logging . basicConfig ( format = FORMAT )
log = logging . getLogger ( ' myLogger ' )
parser = argparse . ArgumentParser ( )
2019-05-30 17:19:54 +00:00
parser . add_argument ( " --khanat-host " , help = " khanat host to auhtenticate " , default = ' localhost ' )
2019-05-19 13:23:03 +00:00
parser . add_argument ( " --suffix " , help = " define suffix " )
parser . add_argument ( " -d " , " --debug " , help = " show debug message " , action = ' store_true ' )
2019-05-19 13:29:43 +00:00
parser . add_argument ( " -p " , " --download-patch " , help = " show debug message " , action = ' store_true ' )
2019-05-19 14:10:18 +00:00
parser . add_argument ( " -s " , " --show-patch-detail " , help = " show debug message " , action = ' store_true ' )
2019-05-30 17:19:54 +00:00
parser . add_argument ( " --size-buffer-file " , help = " size buffer to download file " , type = int , default = 1024 )
parser . add_argument ( " --khanat-port-login " , help = " port http login " , type = int , default = 40916 )
parser . add_argument ( " --khanat-port-frontend " , help = " port UDP frontend " , type = int , default = 47851 )
2019-05-19 13:23:03 +00:00
args = parser . parse_args ( )
if args . debug :
level = logging . getLevelName ( ' DEBUG ' )
else :
level = logging . getLevelName ( ' INFO ' )
log . setLevel ( level )
2019-05-30 17:19:54 +00:00
client = ClientKhanat ( args . khanat_host , khanat_port_login = args . khanat_port_login , khanat_port_frontend = args . khanat_port_frontend , suffix = args . suffix , download_patch = args . download_patch , show_patch_detail = args . show_patch_detail , size_buffer_file = args . size_buffer_file )
2019-05-19 13:23:03 +00:00
client . Emulate ( )
log . info ( " End " )
if __name__ == " __main__ " :
2019-05-31 17:25:04 +00:00
#TestBitStream()
#TestCBitSet()
2019-05-19 14:10:18 +00:00
main ( )