├── .gitignore ├── README.md └── tips ├── BaseApp ├── KBEngine.py └── __init__.py └── CellApp ├── KBEngine.py └── __init__.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | 5 | # C extensions 6 | *.so 7 | 8 | # Distribution / packaging 9 | .Python 10 | env/ 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | lib/ 17 | lib64/ 18 | parts/ 19 | sdist/ 20 | var/ 21 | *.egg-info/ 22 | .installed.cfg 23 | *.egg 24 | 25 | # PyInstaller 26 | # Usually these files are written by a python script from a template 27 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 28 | *.manifest 29 | *.spec 30 | 31 | # Installer logs 32 | pip-log.txt 33 | pip-delete-this-directory.txt 34 | 35 | # Unit test / coverage reports 36 | htmlcov/ 37 | .tox/ 38 | .coverage 39 | .cache 40 | nosetests.xml 41 | coverage.xml 42 | 43 | # Translations 44 | *.mo 45 | *.pot 46 | 47 | # Django stuff: 48 | *.log 49 | 50 | # Sphinx documentation 51 | docs/_build/ 52 | 53 | # PyBuilder 54 | target/ 55 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | KBEngine-Python-Tips 2 | =================================== 3 | 4 | github地址(海外):https://github.com/likecg2010/KBEngine-Python-Tips 5 | 6 | 开源中国地址(中国镜像):http://git.oschina.net/likecg/KBEngine-Python-Tips 7 | 8 | 9 | 10 | 这个项目是为了给KBEngine服务端编写Python脚本的时候,让IDE有语法提示。 11 | 12 | ## 1.用法 13 | 1.1下载项目之后,把tips目录下的所有文件拷贝到python安装目录的Lib下即可使用,比如windows平台上的,C:\Python34\Lib。 14 | 15 | 16 | 1.2使用Python IDE编辑器就可以出现语法提示了。 17 | 18 | 19 | 1.3写Baseapp的python脚本的时候,导入请写 20 | 21 | 22 | from BaseApp import KBEngine #IDE语法提示时候用,放入服务端时候,注释掉这行 23 | 24 | 25 | \#import KBEngine #放入服务端时候,启用这行 26 | 27 | 28 | 29 | 语法提示的时候请用第一行的导入语句,完成脚本编写之后,注释掉,用启用第二行的语句。因为实际源于KBEngine模块 30 | 31 | 1.4写Cellapp的python脚本的时候,导入请写 32 | 33 | from CellApp import KBEngine #IDE语法提示时候用,放入服务端时候,注释掉这行 34 | 35 | 36 | \#import KBEngine #放入服务端时候,启用这行 37 | 38 | 语法提示的时候请用第一行的导入语句,完成脚本编写之后,注释掉,用启用第二行的语句。因为实际源于KBEngine模块 39 | 40 | 1.5建议是使用Pycharm做Python IDE编辑器,提示效果最好,可以提高开发效率。 41 | 42 | ## 2.Pycharm语法提示效果 43 | 2.1 想要重写继承父类的子类的函数,鼠标右键Generate,可以选择重写哪个函数。 44 | 45 | 2.1图 46 | 47 | 列表列出父类可供重写的方法 48 | ![](http://t2.qpic.cn/mblogpic/e40d9421ab85418772a0/2000) 49 | 50 | 点击想要重写的方法,Pycharm生成重写的方法 51 | ![](http://t2.qpic.cn/mblogpic/b4cb7833b91f6aa7788e/2000) 52 | 53 | 54 | 55 | 56 | 2.2 调用父类函数,可以语法提示 57 | 58 | 2.2图 59 | 语法提示效果 60 | ![](http://t2.qpic.cn/mblogpic/5e88bbe757ce36afbdbe/2000) 61 | 62 | 63 | 64 | 2.3 在函数上按住Ctrl+Q键可以看到函数的相关文档 65 | 66 | 2.3图 67 | 文档提示效果 68 | ![](http://t2.qpic.cn/mblogpic/8f48fd6888c3a9f366a6/2000) 69 | 70 | #### **备注,项目中的两个Python脚本文件只是用于IDE提示,里面只是函数的签名和文档,没有实际运行的效果,如果项目存在错漏,请大家帮助完善。 71 | -------------------------------------------------------------------------------- /tips/BaseApp/KBEngine.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | 4 | from enum import Enum 5 | 6 | 7 | class EntitiesObject(object): 8 | pass 9 | 10 | #该属性不确定这样定义 11 | class CellObject(object): 12 | pass 13 | 14 | 15 | # --------------KBEngine模块的成员属性-------------------------------- 16 | 17 | LOG_ON_ACCEPT = 0 18 | LOG_ON_REJECT = 0 19 | LOG_ON_WAIT_FOR_DESTROY = 0 20 | LOG_TYPE_DBG = 0 21 | LOG_TYPE_ERR = 0 22 | LOG_TYPE_INFO = 0 23 | LOG_TYPE_NORMAL = 0 24 | LOG_TYPE_WAR = 0 25 | 26 | #该属性不确定这样定义 27 | NEXT_ONLY = 2 28 | """ 29 | 说明: 30 | 31 | 这个常量用于Base.shouldAutoBackup和Base.shouldAutoArchive属性。 32 | 这个值意指在下一次认为可以的时候自动备份该实体,然后这个属性自动设为False(0)。 33 | """ 34 | #该属性不确定这样定义 35 | component="应该是只读的属性吧" 36 | 37 | #该属性不确定这样定义 38 | entities=EntitiesObject() 39 | """ 40 | 说明: 41 | 42 | entities是一个字典对象,包含当前进程上所有的实体。 43 | 调试泄露的实体(调用过destroy却没有释放内存的实体,通常是由于被引用导致无法释放): 44 | 45 | >>> KBEngine.entities.garbages.items() 46 | [(1025, Avatar object at 0x7f92431ceae8.)] 47 | 48 | >>> e = _[0][1] 49 | >>> import gc 50 | >>> gc.get_referents(e) 51 | [{'spacesIsOk': True, 'bootstrapIdx': 1}, ] 52 | 53 | 54 | 调试泄露的KBEngine封装的Python对象: 55 | KBEngine.debugTracing 56 | 类型: Entities 57 | """ 58 | 59 | baseAppData={ } 60 | """ 61 | 说明: 62 | 63 | 这个属性包含一个类字典的对象,这个对象会在所有的BaseApps之间自动同步。当字典的一个值被修改,这个修改会广播到所有的BaseApps。 64 | 65 | 例子: 66 | KBEngine.baseAppData[ "hello" ] = "there" 67 | 68 | 69 | 70 | 其余BaseApps可以访问下面的: 71 | print KBEngine.baseAppData[ "hello" ] 72 | 73 | 74 | 75 | 键和值可以是任意类型,但这些类型必须在所有目标组件上能够被封装和被拆封。 76 | 77 | 当一个值被改变或被删除,一个回调函数会在所有组件被调用。参看:KBEngine.onBaseAppData和KBEngine.onDelBaseAppData。 78 | 79 | 注意:只有顶层的值才会被广播,如果你有一个值(比如一个列表),它改变了内部的值(比如只是改变一个数),这个信息不会被广播。 80 | 81 | 不要进行下面的操作: 82 | KBEngine.baseAppData[ "list" ] = [1, 2, 3] 83 | KBEngine.baseAppData[ "list" ][1] = 7 84 | 85 | 这样,本地访问是[1, 7, 3],远程访问是[1, 2, 3]。 86 | """ 87 | 88 | globalData={} 89 | """ 90 | 说明: 91 | 92 | 这个属性包含一个类字典的对象,这个对象会在所有的BaseApps和CellApps之间自动同步。当字典的一个值被修改,这个修改会广播到所有的BaseApps和CellApps。 93 | 94 | 例子: 95 | KBEngine.globalData[ "hello" ] = "there" 96 | 97 | 98 | 99 | 其余Baseapp或者Cellapp可以访问下面的: 100 | print KBEngine.globalData[ "hello" ] 101 | 102 | 103 | 104 | 键和值可以是任意类型,但这些类型必须在所有目标组件上能够被封装和被拆封。 105 | 106 | 当一个值被改变或被删除,一个回调函数会在所有组件被调用。参看:KBEngine.onGlobalData和KBEngine.onGlobalDataDel。 107 | 108 | 注意:只有顶层的值才会被广播,如果你有一个值(比如一个列表),它改变了内部的值(比如只是改变一个数),这个信息不会被广播。 109 | 110 | 不要进行下面的操作: 111 | KBEngine.globalData[ "list" ] = [1, 2, 3] 112 | KBEngine.globalData[ "list" ][1] = 7 113 | 114 | 这样,本地访问是[1, 7, 3],远程访问是[1, 2, 3]。 115 | 116 | """ 117 | 118 | 119 | #--------------------KBEngine的成员函数----------------------------------- 120 | 121 | 122 | 123 | def addWatcher(path, datatype, getFunction): 124 | """ 125 | 功能说明: 126 | 127 | 与调试监视系统交互,允许用户向监视系统注册一个监视变量。 128 | 129 | 例: 130 | 131 | 132 | 133 | 这个函数添加一个监视变量在"scripts/players"监视路径之下。函数countPlayers在观察者观察时被调用。 134 | 135 | @param path: 创建监视的路径。 136 | @param datatype: 监视变量的值类型。参考: 基本类型 137 | @param getFunction: 这个函数当观察者检索该变量时调用。这个函数不带参数返回一个代表监视变量的值。 138 | 139 | 140 | """ 141 | pass 142 | 143 | 144 | def address(): 145 | """ 146 | 功能说明: 147 | 148 | 返回内部网络接口的地址。 149 | 150 | 151 | """ 152 | pass 153 | 154 | 155 | def Blob(): 156 | """ 157 | 功能说明: 158 | 159 | 返回一个新的blob对象。 160 | 161 | Blob对象存储的是二进制信息,提供这个类型是为了让用户能够方便的序列化与反序列化Python基本类型同时能与KBEngine底层序列化规则相同。 162 | 163 | 164 | 例如:你可以使用这个对象构造一个KBEngine能解析的网络数据包。 165 | 166 | 用法: 167 | >>> s = KBEngine.Blob() 168 | >>> s 169 | >>> b'' 170 | >>> s.append("UINT32", 1) 171 | >>> s.pop("UINT32") 172 | >>> 1 173 | 174 | 目前Blob能够支持的类型仅为基本数据类型。参考: 基本类型 175 | 176 | """ 177 | pass 178 | 179 | def charge(ordersID, dbID, byteDatas, pycallback): 180 | """ 181 | 功能说明: 182 | 183 | 计费接口。 184 | @param ordersID:string,订单ID。 185 | @param dbID:uint64,实体的databaseID。 186 | @param byteDatas:bytes或BLOB,附带数据,由开发者自己解析和定义。 187 | @param pycallback:计费回调。 188 | 计费回调原型: 189 | def on**ChargeCB(self, orderID, dbID, success, datas): 190 | ordersID:string,订单ID 191 | dbID:uint64,通常为entity的databaseID 192 | success:bool,是否成功 193 | datas:bytes或BLOB,附带数据,由开发者自己解析和定义 194 | 195 | @return: 196 | """ 197 | pass 198 | 199 | 200 | def createBase(): 201 | """ 202 | 功能说明: 203 | 204 | KBEngine.createBaseLocally的别名. 205 | 206 | @return: 207 | """ 208 | pass 209 | 210 | 211 | def createBaseAnywhere(entityType, *params, callback): 212 | """ 213 | 功能说明: 214 | 215 | 创建一个新的Base实体,服务端可能选择任何的Baseapp来创建Base实体。 216 | 217 | 这个方法应作为KBEngine.createBaseLocally的首选,这样服务端会灵活地选择一个合适的Baseapp来创建实体。 218 | 219 | 函数参数需要创建的实体的类型,还有一个Python字典作为参数来初始化实体的值。 220 | 221 | 这个Python字典不需要用户提供所有的属性,没有提供的属性默认为实体定义文件".def"提供的默认值。 222 | 223 | 例子: 224 | 225 | params = { 226 | "name" : "kbe", # base, BASE_AND_CLIENT 227 | "HP" : 100, # cell, ALL_CLIENT, in cellData 228 | "tmp" : "tmp" # baseEntity.tmp 229 | } 230 | 231 | def onCreateBaseCallback(entity) 232 | print(entity) 233 | 234 | createBaseAnywhere("Avatar", params, onCreateBaseCallback) 235 | 236 | 237 | @param entityType:string,指定要创建的Base实体的类型。有效的实体类型在/scripts/entities.xml列出。 238 | @param params:可选参数, 一个Python字典对象。如果一个指定的键是一个Base属性,他的值会用来初始化这个Base实体的属性。 239 | 如果这个键是一个Cell属性,它会被添加到Base实体的'cellData'属性,这个'cellData'属性是一个Python字典,然后在后面会用来初始化cell实体的属性。 240 | @param callback:callback是一个可选的回调函数,当实体完成创建时被调用。回调函数带有一个参数,当成功的时候是Base实体的mailbox,失败时是None。 241 | @return:Base实体的mailbox。 242 | 243 | """ 244 | pass 245 | 246 | 247 | def createBaseFromDBID(entityType, dbID, callback): 248 | """ 249 | 功能说明: 250 | 251 | 从数据库里加载数据创建一个Base实体。这个新的Base实体会在调用这个函数的Baseapp上创建。 252 | 如果该实体已经从数据库检出,那么将返回这个存在的Base实体的引用。 253 | @param entityType:string,指定要创建的Base实体的类型。有效的实体类型在/scripts/entities.xml列出。 254 | @param dbID:这是一个指定要创建的实体的数据库ID。这个实体的数据库ID存储在该实体的databaseID属性。 255 | @param callback:这是一个可选的回调函数,当操作完成的时候它会被调用。回调函数带有3个参数:baseRef,databaseID和wasActive。如果操作成功,baseRef会是一个mailbox或者是新创建的Base实体的直接引用,databaseID会是实体的数据库ID,无论该实体是否已经激活 256 | wasActive都会有所指示,如果wasActive是True则baseRef是已经存在的实体的引用(已经从数据库检出)。如果操作失败,baseRef会是None,databaseID会是0, 257 | wasActive会是False。失败最常见的原因是实体在数据库里不存在,但偶尔也会出现其它错误比如说超时或者是分配ID失败。 258 | 259 | """ 260 | pass 261 | 262 | 263 | def createBaseAnywhereFromDBID(entityType, dbID, callback): 264 | """ 265 | 功能说明: 266 | 267 | 从数据库里加载数据创建一个Base实体。服务端可能选择任何的Baseapp来创建Base实体。 268 | 269 | 使用这个函数将有助于BaseApps负载平衡。 270 | 271 | 如果该实体已经从数据库检出,那么将返回这个存在的Base实体的引用。 272 | 273 | 274 | 275 | @param entityType:string,指定要创建的Base实体的类型。有效的实体类型在/scripts/entities.xml列出。 276 | @param dbID:这是一个指定要创建的实体的数据库ID。这个实体的数据库ID存储在该实体的databaseID属性。 277 | @param callback:这是一个可选的回调函数,当操作完成的时候它会被调用。回调函数带有3个参数:baseRef,databaseID和wasActive。如果操作成功,baseRef会是一个mailbox或者是新创建的Base实体的直接引用,databaseID会是实体的数据库ID,无论该实体是否已经激活 278 | wasActive都会有所指示,如果wasActive是True则baseRef是已经存在的实体的引用(已经从数据库检出)。如果操作失败,baseRef会是None,databaseID会是0, 279 | wasActive会是False。失败最常见的原因是实体在数据库里不存在,但偶尔也会出现其它错误比如说超时或者是分配ID失败。 280 | @return:Base实体的mailbox。 281 | 282 | """ 283 | pass 284 | 285 | 286 | def createBaseLocally(entityType, *params): 287 | """ 288 | 功能说明: 289 | 290 | 创建一个新的Base实体。 291 | 函数参数需要创建的实体的类型,还有一个Python字典作为参数来初始化实体的值。 292 | 293 | 这个Python字典不需要用户提供所有的属性,没有提供的属性默认为实体定义文件".def"提供的默认值。 294 | 295 | KBEngine.createBaseAnywhere应该作为这个方法的首选,因为服务端可以灵活地在合适的Baseapp上创建实体。 296 | 297 | 例子: 298 | 299 | params = { 300 | "name" : "kbe", # base, BASE_AND_CLIENT 301 | "HP" : 100, # cell, ALL_CLIENT, in cellData 302 | "tmp" : "tmp" # baseEntity.tmp 303 | } 304 | 305 | baseEntity = createBaseLocally("Avatar", params) 306 | 307 | 308 | @param entityType:string,指定要创建的Base实体的类型。有效的实体类型在/scripts/entities.xml列出。 309 | @param params:可选参数, 一个Python字典对象。如果一个指定的键是一个Base属性,他的值会用来初始化这个Base实体的属性。 310 | 如果这个键是一个Cell属性,它会被添加到Base实体的'cellData'属性,这个'cellData'属性是一个Python字典,然后在后面会用来初始化cell实体的属性。 311 | @return:新创建的Base实体(参考Base) 312 | 313 | """ 314 | pass 315 | 316 | 317 | def createEntity(): 318 | """ 319 | 功能说明: 320 | 321 | KBEngine.createBaseLocally的别名. 322 | @return: 323 | """ 324 | pass 325 | 326 | 327 | 328 | def debugTracing(): 329 | """ 330 | 功能说明: 331 | 332 | 输出当前KBEngine追踪的Python扩展对象计数器。 333 | 扩展对象包括:固定字典、固定数组、Entity、Mailbox... 334 | 在服务端正常关闭时如果计数器不为零,此时说明泄露已存在,日志将会输出错误信息。 335 | 336 | ERROR cellapp [0x0000cd64] [2014-11-12 00:38:07,300] - PyGC::debugTracing(): FixedArray : leaked(128) 337 | ERROR cellapp [0x0000cd64] [2014-11-12 00:38:07,300] - PyGC::debugTracing(): EntityMailbox : leaked(8) 338 | 339 | 340 | 341 | """ 342 | pass 343 | 344 | 345 | 346 | def delWatcher(path): 347 | """ 348 | 功能说明: 349 | 350 | 与调试监视系统交互,允许用户在脚本删除监视的变量。 351 | @param path:path 要删除的变量的路径。 352 | """ 353 | pass 354 | 355 | 356 | def deleteBaseByDBID(entityType, dbID, callback): 357 | """ 358 | 功能说明: 359 | 360 | 从数据库删除指定的实体(包括属性所产生的子表数据),如果实体没有从数据库检出则删除成功, 361 | 如果实体已经从数据库检出那么KBEngine服务系统将会删除失败,并且从回调中返回 Base实体的mailbox。 362 | 363 | @param entityType:string,指定要删除的Base实体的类型。有效的实体类型在/scripts/entities.xml列出。 364 | @param dbID:指定要删除的实体的数据库ID。这个实体的数据库ID存储在该实体的databaseID属性。 365 | @param callback:callback是一个可选的回调函数,只有一个参数,当实体没有从数据库检出时将会成功删除数据,参数是True。 366 | 如果实体已经从数据库检出那么参数是Base实体的mailbox。 367 | 368 | """ 369 | pass 370 | 371 | 372 | def deregisterFileDescriptor(fileDescriptor): 373 | """ 374 | 功能说明: 375 | 376 | 注销已经通过KBEngine.registerFileDescriptor注册的回调。 377 | 378 | 例子: 379 | http://www.kbengine.org/assets/other/py/Poller.py 380 | @param fileDescriptor:socket描述符/文件描述符。 381 | 382 | 383 | """ 384 | pass 385 | 386 | 387 | def deregisterWriteFileDescriptor(fileDescriptor): 388 | """ 389 | 功能说明: 390 | 391 | 注销已经通过KBEngine.registerWriteFileDescriptor注册的回调。 392 | 393 | 例子: 394 | http://www.kbengine.org/assets/other/py/Poller.py 395 | 396 | @param fileDescriptor:socket描述符/文件描述符。 397 | 398 | 399 | @return: 400 | """ 401 | pass 402 | 403 | 404 | def executeRawDatabaseCommand(command, callback, threadID): 405 | """ 406 | 功能说明: 407 | 408 | 这个脚本函数在数据库上执行原始数据库命令,该命令将直接由相关数据库进行解析。 409 | 410 | 请注意使用该函数修改实体数据可能不生效,因为如果实体已经检出,被修改过的实体数据将仍会被实体存档而导致覆盖。 411 | 强烈不推荐这个函数用于读取或修改实体数据。 412 | @param command:这个数据库命令将会因为不同数据库配置方案而不同。对于方案为MySQL数据库它是一个SQL查询语句。 413 | @param callback: 414 | 可选参数,带有命令执行结果的回调对象(比如说是一个函数)。这个回调带有3个参数:结果集合,影响的行数与错误信息。 415 | 416 | 这个结果集合参数是一个行列表。每一行是一个包含字段值的字符串列表。命令执行没有返回结果集合(比如说是DELETE命令),或者 417 | 命令执行有错误时这个结果集合为None。 418 | 419 | 这个数字是命令执行受影响的行数。这个参数只和不返回结果结合的命令(如DELETE)相关。 420 | 如果有结果集合返回或者命令执行有错误时这个参数为None。 421 | 422 | 命令执行有错误时这个错误信息参数是一个描述错误的字符串。命令执行没有发生错误时这个参数为None。 423 | @param threadID: 424 | int32,可选参数,指定一个线程来处理本条命令。用户可以通过这个参数控制某一类命令的执行先后顺序(dbmgr是多线程处理的),默认是不指定,如果threadID是实体的ID, 425 | 那么将加入到该实体的存档队列中由线程逐条写入。 426 | 427 | """ 428 | pass 429 | 430 | 431 | 432 | def genUUID64(): 433 | """ 434 | 功能说明: 435 | 436 | 该函数生成一个64位的唯一ID。 437 | 注意:这个函数依赖于Baseapps服务进程启动参数cid与globalorder,请正确设置启动参数保持唯一性。 438 | 439 | 用途: 440 | 多个服务进程上产生唯一物品ID并且在合服时不会产生冲突。 441 | 多个服务进程上产生一个房间ID,不需要进行唯一性校验。 442 | 443 | 444 | @return:返回一个64位的integer。 445 | """ 446 | 447 | 448 | pass 449 | 450 | 451 | def getResFullPath(res): 452 | """ 453 | 功能说明: 454 | 455 | 获取资源的绝对路径。 456 | 注意:资源必须在KBE_RES_PATH之下才可以访问到。 457 | 458 | @param res:string,资源的相对路径。 459 | @return:string,资源的绝对路径。 460 | 461 | 462 | """ 463 | 464 | 465 | pass 466 | 467 | 468 | 469 | 470 | def getWatcher(path): 471 | """ 472 | 功能说明: 473 | 474 | 从KBEngine调试系统中获取一个监视变量的值。 475 | 476 | 例子:在baseapp1的Python命令行输入: 477 | >>>KBEngine.getWatcher("/root/stats/runningTime") 478 | 12673648533 479 | 480 | >>>KBEngine.getWatcher("/root/scripts/players") 481 | 32133 482 | 483 | @param path:string,该变量的绝对路径包括变量名(可以在GUIConsole的watcher页查看)。 484 | @return:该变量的值。 485 | 486 | 487 | """ 488 | pass 489 | 490 | 491 | def getWatcherDir(path): 492 | """ 493 | 功能说明: 494 | 495 | 从KBEngine调试系统中获取一个监视目录下的元素列表(目录、变量名)。 496 | 497 | 例子:在baseapp1的Python命令行输入: 498 | >>>KBEngine.getWatcher("/root") 499 | ('stats', 'objectPools', 'network', 'syspaths', 'ThreadPool', 'cprofiles', 'scripts', 'numProxices', 'componentID', 'componentType', 'uid', 'numClients', 'globalOrder', 'username', 'load', 'gametime', 'entitiesSize', 'groupOrder') 500 | 501 | @param path:string,该变量的绝对路径(可以在GUIConsole的watcher页查看)。 502 | @return:监视目录下的元素列表(目录、变量名)。 503 | """ 504 | pass 505 | 506 | 507 | def hasRes(res): 508 | """ 509 | 功能说明: 510 | 511 | 使用这个接口可以判断一个相对路径的资源是否存在。 512 | 注意:资源必须在KBE_RES_PATH之下才可以访问到。 513 | 514 | 例子: 515 | 516 | >>>KBEngine.hasRes("scripts/entities.xml") 517 | True 518 | 519 | @param res:string,资源的相对路径。 520 | @return:BOOL, 存在返回True,否则返回False。 521 | 522 | """ 523 | pass 524 | 525 | 526 | def isShuttingDown(): 527 | """ 528 | 功能说明: 529 | 530 | 返回服务端是否正在关闭中。在onBaseAppShuttingDown回调函数被调用后,这个函数返回True。 531 | @return:系统正在关闭返回True,否则返回False。 532 | 533 | 534 | """ 535 | pass 536 | 537 | 538 | def listPathRes(path, extension): 539 | """ 540 | 功能说明: 541 | 542 | 获得一个资源目录下的资源列表。 543 | 注意:资源必须在KBE_RES_PATH之下才可以访问到。 544 | 545 | 例子: 546 | 547 | >>>KBEngine.listPathRes("scripts/cell/interfaces") 548 | ('/home/kbe/kbengine/demo/res/scripts/cell/interfaces/AI.py', '/home/kbe/kbengine/demo/res/scripts/cell/interfaces/新建文本文档.txt') 549 | 550 | >>>KBEngine.listPathRes("scripts/cell/interfaces", "txt") 551 | ('/home/kbe/kbengine/demo/res/scripts/cell/interfaces/新建文本文档.txt') 552 | 553 | >>>KBEngine.listPathRes("scripts/cell/interfaces", "txt|py") 554 | ('/home/kbe/kbengine/demo/res/scripts/cell/interfaces/AI.py', '/home/kbe/kbengine/demo/res/scripts/cell/interfaces/新建文本文档.txt') 555 | 556 | >>>KBEngine.listPathRes("scripts/cell/interfaces", ("txt", "py")) 557 | ('/home/kbe/kbengine/demo/res/scripts/cell/interfaces/AI.py', '/home/kbe/kbengine/demo/res/scripts/cell/interfaces/新建文本文档.txt') 558 | 559 | @param path:string,资源的相对路径。 560 | @param extension:string,可选参数,扩展名。 561 | 562 | 563 | @return:Tuple, 资源列表。 564 | """ 565 | pass 566 | 567 | 568 | def lookUpBaseByDBID( entityType, dbID, callback ): 569 | """ 570 | 功能说明: 571 | 572 | 查询一个实体是否从数据库检出,如果实体已经从数据库检出那么KBEngine服务系统将从回调中返回Base实体的mailbox。 573 | 574 | @param entityType:string,指定要查询的Base实体的类型。有效的实体类型在/scripts/entities.xml列出。 575 | @param dbID:指定要查询的Base实体的数据库ID。这个实体的数据库ID存储在该实体的databaseID属性。 576 | @param callback:callback只有一个参数,当实体没有从数据库检出时将会返回True。 577 | 如果实体已经从数据库检出那么将返回Base实体的mailbox, 其他任何情况返回False。 578 | 579 | 580 | """ 581 | 582 | def matchPath(res): 583 | """ 584 | 功能说明: 585 | 586 | 使用相对路径的资源获得资源的绝对路径。 587 | 注意:资源必须在KBE_RES_PATH之下才可以访问到。 588 | 589 | 例子: 590 | 591 | >>>KBEngine.matchPath("scripts/entities.xml") 592 | '/home/kbe/kbengine/demo/res/scripts/entities.xml' 593 | 594 | @param res:string,资源的相对路径(包括资源名称)。 595 | @return:string, 资源的绝对路径。 596 | """ 597 | pass 598 | 599 | 600 | def open(res, mode): 601 | """ 602 | 功能说明: 603 | 604 | 使用这个接口可以使用相对路径来打开相关资源。注意:资源必须在KBE_RES_PATH之下才可以访问到。 605 | @param res:string,资源的相对路径。 606 | @param mode:string,文件操作模式: 607 | w 以写方式打开, 608 | a 以追加模式打开 (从 EOF 开始, 必要时创建新文件) 609 | r+ 以读写模式打开 610 | w+ 以读写模式打开 (参见 w ) 611 | a+ 以读写模式打开 (参见 a ) 612 | rb 以二进制读模式打开 613 | wb 以二进制写模式打开 (参见 w ) 614 | ab 以二进制追加模式打开 (参见 a ) 615 | rb+ 以二进制读写模式打开 (参见 r+ ) 616 | wb+ 以二进制读写模式打开 (参见 w+ ) 617 | ab+ 以二进制读写模式打开 (参见 a+ ) 618 | 619 | @return: 620 | """ 621 | pass 622 | 623 | 624 | def publish(): 625 | """ 626 | 功能说明: 627 | 628 | 这个接口返回当前服务端发行模式。 629 | 630 | @return:int8,0:debug,1:release,其它可自定义。 631 | """ 632 | pass 633 | 634 | def quantumPassedPercent(): 635 | """ 636 | 功能说明: 637 | 638 | 返回取得当前tick占用一个时钟周期的百分比。 639 | @return:返回取得当前tick占用一个时钟周期的百分比。 640 | 641 | 642 | """ 643 | pass 644 | 645 | def registerFileDescriptor(fileDescriptor, callback): 646 | """ 647 | 功能说明: 648 | 649 | 注册一个回调函数,这个回调函数当文件描述符可读时被调用。 650 | 651 | 例子: 652 | http://www.kbengine.org/assets/other/py/Poller.py 653 | 654 | @param fileDescriptor:socket描述符/文件描述符。 655 | @param callback:一个回调函数,socket描述符/文件描述符作为它的唯一参数。 656 | 657 | """ 658 | pass 659 | 660 | 661 | def registerWriteFileDescriptor(fileDescriptor, callback): 662 | """ 663 | 664 | 功能说明: 665 | 666 | 注册一个回调函数,这个回调函数当socket描述符/文件描述符可写时被调用。 667 | 668 | 例子: 669 | http://www.kbengine.org/assets/other/py/Poller.py 670 | 671 | @param fileDescriptor:socket描述符/文件描述符。 672 | @param callback: 一个回调函数,socket描述符/文件描述符作为它的唯一参数。 673 | """ 674 | pass 675 | 676 | 677 | def reloadScript(fullReload): 678 | """ 679 | 功能说明: 680 | 681 | 重新加载与实体和自定义数据类型相关的Python模块。当前实体类会设置为新加载的类。这个方法应该只用于开发模式,对于产品模式不合适。下面几点应该注意: 682 | 683 | 1)重载脚本仅仅能在Cellapp上执行, 用户应该确保所有的服务端组件加载完成。 684 | 685 | 2)自定义类型在脚本重载后应该确保内存中已经实例化的对象也被更新,下面是一个例子: 686 | 687 | 688 | for e in KBEngine.entities.values(): 689 | if type( e ) is Avatar.Avatar: 690 | e.customData.__class__ = CustomClass 691 | 692 | 当这个方法完成时 KBEngine.onInit( True ) 被调用。 693 | 694 | @param fullReload:可选的boolean参数,指定是否同时重新加载实体定义。如果这个参数为False,则实体定义不会被重新加载。默认为True。 695 | @return:重新加载成功返回True,否则返回False。 696 | 697 | 698 | """ 699 | pass 700 | 701 | 702 | def scriptLogType(logType): 703 | """ 704 | 功能说明: 705 | 706 | 设置当前Python.print输出的信息类型(参考: KBEngine.LOG_TYPE_*)。 707 | 708 | @param logType: 709 | @return: 710 | """ 711 | 712 | 713 | pass 714 | 715 | def time(): 716 | """ 717 | 功能说明: 718 | 719 | 这个方法返回当前游戏的时间(周期数)。 720 | @return:uint32,当前游戏的时间,这里指周期数,周期受频率影响,频率由配置文件kbengine.xml或者kbengine_defs.xml->gameUpdateHertz决定。 721 | """ 722 | pass 723 | 724 | 725 | 726 | # 回调函数 727 | 728 | def onBaseAppReady(bootstrapIdx): 729 | """ 730 | 功能说明: 731 | 732 | 当前Baseapp进程已经准备好的时候回调此函数。 733 | 注意:该回调接口必须实现在入口模块(kbengine_defs.xml->entryScriptFile)中。 734 | 735 | @param bootstrapIdx:当前进程在多个Baseapp中的启动顺序(从1开始计数)。 736 | 737 | """ 738 | pass 739 | 740 | 741 | def onBaseAppShutDown(state): 742 | """ 743 | 功能说明: 744 | 745 | Baseapp关闭过程会回调此函数。 746 | 注意:该回调接口必须实现在入口模块(kbengine_defs.xml->entryScriptFile)中。 747 | @param state:如果state为0,意指在断开所有客户端之前,如果state为1, 748 | 意指在将所有实体写入数据库之前,如果state为2,意指在所有实体被写入数据库之后。 749 | """ 750 | pass 751 | 752 | 753 | def onCellAppDeath(addr): 754 | """ 755 | 功能说明: 756 | 757 | 某个cellapp死亡会回调此函数。 758 | 注意:该回调接口必须实现在入口模块(kbengine_defs.xml->entryScriptFile)中。 759 | @param addr:死亡的cellapp地址。 760 | tuple:(ip, port) 网络字节序 761 | 762 | """ 763 | pass 764 | 765 | 766 | def onFini(): 767 | """ 768 | 功能说明: 769 | 770 | 引擎正式关闭后回调此函数。 771 | 注意:该回调接口必须实现在入口模块kbengine_defs.xml->entryScriptFile)中。 772 | 773 | """ 774 | pass 775 | 776 | 777 | def onBaseAppData(key, value): 778 | """ 779 | 功能说明: 780 | 781 | KBEngine.baseAppData有改变时回调此函数。 782 | 注意:该回调接口必须实现在入口模块(kbengine_defs.xml->entryScriptFile)中。 783 | 784 | @param key:被改变数据的键。 785 | @param value:被改变数据的值。 786 | """ 787 | pass 788 | 789 | 790 | def onBaseAppDataDel(key): 791 | """ 792 | 功能说明: 793 | 794 | KBEngine.baseAppData有删除的时候回调此函数。 795 | 注意:该回调接口必须实现在入口模块(kbengine_defs.xml->entryScriptFile)中。 796 | 797 | @param key:key 被删除数据的键。 798 | """ 799 | pass 800 | 801 | 802 | 803 | def onGlobalData(key, value): 804 | """ 805 | 功能说明: 806 | 807 | KBEngine.globalData有改变的时候回调此函数。 808 | 注意:该回调接口必须实现在入口模块(kbengine_defs.xml->entryScriptFile)中。 809 | @param key:被改变数据的键。 810 | @param value:被改变数据的值。 811 | @return: 812 | """ 813 | pass 814 | 815 | 816 | def onGlobalDataDel(key): 817 | """ 818 | 功能说明: 819 | 820 | KBEngine.globalData有删除的时候回调此函数。 821 | 注意:该回调接口必须实现在入口模块(kbengine_defs.xml->entryScriptFile)中。 822 | 823 | @param key:被删除数据的键。 824 | @return: 825 | """ 826 | pass 827 | 828 | 829 | def onInit(isReload): 830 | """ 831 | 832 | 功能说明: 833 | 834 | 当引擎启动后初始化完所有的脚本后这个接口被调用。 835 | 注意:该回调接口必须实现在入口模块(kbengine_defs.xml->entryScriptFile)中。 836 | 837 | @param isReload:bool,是否是被重写加载脚本后触发的。 838 | @return: 839 | """ 840 | pass 841 | 842 | 843 | 844 | 845 | 846 | 847 | 848 | def onLoseChargeCB(orderID, dbID, success, datas): 849 | """ 850 | 功能说明: 851 | 852 | 当一个订单丢失或者不明订单被处理会收到此回调通知。 853 | 注意:该回调接口必须实现在入口模块(kbengine_defs.xml->entryScriptFile)中。 854 | 855 | @param orderID:string,订单ID。 856 | @param dbID:uint64,实体的数据库ID, 参见: Base.databaseID。 857 | @param success:bool,是否成功。 858 | @param datas:[bytes|BLOB],附带信息。 859 | """ 860 | pass 861 | 862 | 863 | def onReadyForLogin(bootstrapIdx): 864 | """ 865 | 功能说明: 866 | 867 | 当引擎启动并初始化完成后会一直调用此接口询问脚本层是否准备完毕,如果脚本层准备完毕则loginapp允许客户端登录。 868 | 注意:该回调接口必须实现在入口模块(kbengine_defs.xml->entryScriptFile)中。 869 | @param bootstrapIdx:int32,当前进程在多个Baseapp中的启动顺序(从1开始计数)。 870 | @return:返回值大于等于1.0则脚本层准备完成,否则返回准备的进度值0.0~1.0。 871 | """ 872 | pass 873 | 874 | 875 | class CellObject(object): 876 | pass 877 | 878 | 879 | class ClientObject(object): 880 | pass 881 | 882 | 883 | 884 | 885 | class Base: 886 | # -------------------------KBEngine.Base类的成员属性------------------------------- 887 | 888 | 889 | 890 | 891 | __cell = CellObject() 892 | 893 | # 该属性不确定这样写 894 | @property 895 | def cell(self): 896 | """ 897 | 说明: 898 | cell是用于联系cell实体的MAILBOX。这个属性是只读的,且如果这个base实体没有关联的cell时属性是None。 899 | 900 | 类型: 只读 MAILBOX 901 | 902 | """ 903 | return self.__cell 904 | 905 | #该属性不确定这样写,等文档 906 | cellData = {} 907 | """ 908 | cellData 909 | 说明: 910 | 911 | cellData是一个字典属性。每当base实体没有创建它的cell实体时,cell实体的属性会保存在这里。 912 | 913 | 如果cell实体被创建,这些用到的值和cellData属性将被删除。 914 | 除了cell实体在实体定义文件里指定的属性外,它还包含position, direction and spaceID。 915 | 类型: CELLDATADICT 916 | """ 917 | 918 | __className = "" 919 | 920 | @property 921 | def className(self): 922 | """ 923 | 说明: 924 | 925 | 实体的类名。 926 | 类型: 只读,string 927 | """ 928 | return self.__className 929 | 930 | #该属性是不是一个这样定义,不确定 931 | __client = ClientObject() 932 | 933 | @property 934 | def client(self): 935 | """ 936 | 937 | 说明: 938 | 939 | client是用于联系客户端的mailbox。 940 | 这个属性是只读的,且如果这个base实体没有关联的客户端时属性是None。 941 | 类型: 只读 MAILBOX 942 | """ 943 | return self.__client 944 | 945 | __databaseID = 0 #python的原生数据类型中似乎没有int64的类型,如果真的需要int64,需要第三方库 946 | 947 | @property 948 | def databaseID(self): 949 | """ 950 | 说明: 951 | 952 | databaseID是实体的永久ID(数据库id)。这个id是uint64类型且大于0,如果是0则表示该实体不是永久的。 953 | 类型: 只读 int64 954 | @return: 955 | """ 956 | return self.__databaseID 957 | 958 | @property 959 | def id(self): 960 | """ 961 | id是实体的对象id。这个id是一个整型,在base,cell和client相关联的实体之间是相同的。 962 | 这个属性是只读的。 963 | 类型: 只读的,int32 964 | """ 965 | return self.__id 966 | 967 | __isDestroyed = False 968 | 969 | @property 970 | def isDestroyed(self): 971 | """ 972 | 说明: 973 | 974 | 如果该Base实体已经被销毁了,这个属性为True。 975 | 类型: bool 976 | """ 977 | return self.__isDestroyed 978 | 979 | #该属性不确定这样定义,似乎用枚举更好 980 | shouldAutoArchive=True 981 | """ 982 | 说明: 983 | 984 | 这个属性决定了自动存档的策略。 985 | 如果设为True,自动存档将可用,如果设为False,自动存档将不可用。 986 | 如果设为KBEngine.NEXT_ONLY,自动存档将在下一个预定的时间可用,在下一次存档后,这个属性将置为False。 987 | 类型: True, False or KBEngine.NEXT_ONLY 988 | """ 989 | #该属性不确定这样定义,似乎用枚举更好 990 | shouldAutoBackup=True 991 | """ 992 | 说明: 993 | 994 | 这个属性决定了自动备份的策略。 995 | 如果设为True,自动备份将可用,如果设为False,自动备份将不可用。 996 | 如果设为KBEngine.NEXT_ONLY,自动备份将在下一个预定的时间可用,在下一次备份后,这个属性将置为False。 997 | 类型: True, False or KBEngine.NEXT_ONLY 998 | """ 999 | 1000 | 1001 | 1002 | 1003 | 1004 | #------------------KBEngine.Base类的成员函数----------------------------------------- 1005 | 1006 | def addTimer(self, initialOffset, repeatOffset=0, userArg=0): 1007 | """ 1008 | 功能说明: 1009 | 1010 | 注册一个定时器,定时器由回调函数onTimer触发,回调函数将在"initialOffset"秒后被执行第1次,而后将每间隔"repeatOffset"秒执行1次,可设定一个用户参数"userArg"(仅限integer类型)。 1011 | 1012 | onTimer 函数必须在entity的base部分被定义,且带有2个参数,第1个integer类型的是timer的id(可用于移除timer的"delTimer"函数),第2个是用户参数"userArg"。 1013 | 1014 | 例子: 1015 | # 这里是使用addTimer的一个例子 1016 | import KBEngine 1017 | 1018 | class MyBaseEntity( KBEngine.Base ): 1019 | 1020 | def __init__( self ): 1021 | KBEngine.Base.__init__( self ) 1022 | 1023 | # 增加一个定时器,5秒后执行第1次,而后每1秒执行1次,用户参数是9 1024 | self.addTimer( 5, 1, 9 ) 1025 | 1026 | # 增加一个定时器,1秒后执行,用户参数缺省是0 1027 | self.addTimer( 1 ) 1028 | 1029 | # Base的定时器回调"onTimer"被调用 1030 | def onTimer( self, id, userArg ): 1031 | print "MyBaseEntity.onTimer called: id %i, userArg: %i" % ( id, userArg ) 1032 | # if 这是不断重复的定时器,当不再需要该定时器的时候,调用下面函数移除: 1033 | # self.delTimer( id ) 1034 | 1035 | @param initialOffset:float,指定定时器从注册到第一次回调的时间间隔(秒)。 1036 | @param repeatOffset:float,指定第一次回调执行后每次执行的时间间隔(秒)。必须用函数delTimer移除定时器,否则它会一直重复下去。值小于等于0将被忽略。 1037 | @param userArg:integer,指定底层回调"onTimer"时的userArg参数值。 1038 | @return integer,该函数返回timer的内部id,这个id可用于delTimer移除定时器。 1039 | 1040 | 1041 | """ 1042 | pass 1043 | 1044 | def createCellEntity(self, cellEntityMB): 1045 | """ 1046 | 功能说明: 1047 | 1048 | 请求在一个cell里面创建一个关联的实体。 1049 | 1050 | 用于创建cell实体的信息被存储在该实体的属性cellData里。这个属性是一个字典,对应实体的.def文件里的默认值,同时还包括用于表示 1051 | 实体位置和方向(roll, pitch, yaw)的"position", "direction" 和 "spaceID"。 1052 | 1053 | @param cellEntityMB: 一个可选的CellEntityMailBox参数,指定哪个空间里创建这个cell实体的。 1054 | 1055 | 只能使用一个直接的CellEntityMailBox。如果你有一个实体的BaseMailbox,你不可以使用baseMailbox.cell传给这个函数。 1056 | 你必须在这个实体的base上创建一个新的函数来回传这个直接的CellEntityMailBox。 1057 | 1058 | 例如: 1059 | baseMailboxOfNearbyEntity.createCellNearSelf( self ) 1060 | 在实体的base上: 1061 | def createCellNearSelf( self, baseMailbox ): 1062 | baseMailbox.createCellNearHere( self.cell ) 1063 | 在原实体的base上调用createCellNearSelf()方法: 1064 | def createCellNearHere( self. cellMailbox ): 1065 | self.createCellEntity( cellMailbox ) 1066 | 1067 | """ 1068 | pass 1069 | 1070 | 1071 | def createInNewSpace(self): 1072 | """ 1073 | 功能说明: 1074 | 1075 | 在一个空间的cell上创建一个关联的实体,它请求通过cellappmgr来完成。 1076 | 1077 | 用于创建cell实体的信息被存储在该实体的属性cellData里。这个属性是一个字典,对应实体的.def文件里的默认值同时还包括用于表示 1078 | 实体位置和方向(roll, pitch, yaw)的"position", "direction" 和 "spaceID"。 1079 | 1080 | """ 1081 | pass 1082 | 1083 | 1084 | def delTimer(self, id): 1085 | """ 1086 | 功能说明: 1087 | 1088 | 函数delTimer用于移除一个注册的定时器,移除后的定时器不再执行。只执行1次的定时器在执行回调后自动移除,不必要使用delTimer移除。如果delTimer函数使用一个无效的id(例如已经移除),将会产生错误。 1089 | 1090 | 到Base.addTimer参考定时器的一个使用例子。 1091 | 1092 | @param id:integer,它指定要移除的定时器id。 1093 | """ 1094 | pass 1095 | 1096 | 1097 | def destroy(self, deleteFromDB, writeToDB): 1098 | """ 1099 | 功能说明: 1100 | 1101 | 这个函数销毁该实体的base部分。如果实体存在cell部分,那么用户必须先销毁cell部分,否则将会产生错误。要销毁实体的cell部分,调用Base.destroyCellEntity。 1102 | 1103 | 也许在onLoseCell回调里调用self.destroy更为恰当。这能保证实体的base部分被销毁。 1104 | 1105 | @param deleteFromDB:如果是True,在数据库里与这个实体有关联的条目将会被删除,该参数默认为False。 1106 | @param writeToDB:如果是True,与这个实体相关联的存档属性将会写入数据库。 1107 | 只有在这个实体是从数据库读取的或者是使用过Base.writeToDB写入数据库才会被执行。这个参数默认为True,但当deleteFromDB为True的时候它将被忽略。 1108 | 1109 | """ 1110 | pass 1111 | 1112 | 1113 | def destroyCellEntity(self): 1114 | """ 1115 | 功能说明: 1116 | 1117 | destroyCellEntity请求销毁关联的cell实体。如果没有关联的cell实体该方法将会产生错误。 1118 | 1119 | """ 1120 | pass 1121 | 1122 | 1123 | def teleport(self, baseEntityMB): 1124 | """ 1125 | 功能说明: 1126 | 1127 | teleport会瞬移这个实体的cell部分到参数指定的实体所在的空间。 1128 | 1129 | 在抵达新的空间后,Entity.onTeleportSuccess被调用。这可以用来在新的空间里移动该实体到合适的位置。 1130 | 1131 | @param baseEntityMB:实体应该移到的指定实体所在的空间,baseEntityMB即指定实体的mailbox。 1132 | 当成功的时候,与此参数相关联的cell实体会被传入到Entity.onTeleportSuccess函数。 1133 | 1134 | """ 1135 | pass 1136 | 1137 | 1138 | def writeToDB(self, callback, shouldAutoLoad): 1139 | """ 1140 | 功能说明: 1141 | 1142 | 该函数保存这个实体的存档属性到数据库,使得以后需要的时候可以重新从数据库加载。 1143 | 1144 | 实体也可以被标记为自动加载,这样当服务启动后实体将会被重新创建。 1145 | 1146 | @param callback:这个可选参数是当数据库操作完成后的回调函数。它有两个参数。第一个是boolean类型标志成功或失败,第二个是base实体。 1147 | @param shouldAutoLoad:这个可选参数指定这个实体在服务启动的时候是否需要从数据库加载。 1148 | 1149 | """ 1150 | pass 1151 | 1152 | 1153 | # Base类回调函数 1154 | 1155 | 1156 | def onCreateCellFailure(self): 1157 | """ 1158 | 功能说明: 1159 | 1160 | 如果这个函数在脚本中有实现,这个函数在cell实体创建失败的时候被调用。这个函数没有参数。 1161 | 1162 | """ 1163 | pass 1164 | 1165 | 1166 | def onDestroy(self): 1167 | """ 1168 | 功能说明: 1169 | 1170 | 如果这个函数在脚本中有实现,这个函数在调用Base.destroy()后,在实际销毁之前被调用。这个函数没有参数。 1171 | 1172 | 1173 | """ 1174 | pass 1175 | 1176 | 1177 | def onGetCell(self): 1178 | """ 1179 | 功能说明: 1180 | 1181 | 如果这个函数在脚本中有实现,这个函数在它获得cell实体的时候被调用。这个函数没有参数。 1182 | 1183 | 1184 | """ 1185 | pass 1186 | 1187 | 1188 | def onLoseCell(self): 1189 | """ 1190 | 功能说明: 1191 | 1192 | 如果这个函数在脚本中有实现,这个函数在它关联的cell实体销毁之后被调用。这个函数没有参数。 1193 | 1194 | 1195 | """ 1196 | pass 1197 | 1198 | 1199 | def onPreArchive(self): 1200 | """ 1201 | 功能说明: 1202 | 1203 | 如果这个函数在脚本中有实现,这个函数在该实体自动写入数据库之前被调用。这个回调在Base.onWriteToDB回调之前被调用。 1204 | 如果该回调返回False,该归档操作中止。这个回调应该返回True使得操作继续。如果这个回调不存在,则归档操作继续进行。 1205 | 1206 | 1207 | """ 1208 | pass 1209 | 1210 | 1211 | def onRestore(self): 1212 | """ 1213 | 功能说明: 1214 | 1215 | 如果这个函数在脚本中有实现,这个函数在Base应用程序崩溃后在其它Base应用程序上重新创建该实体时被调用。这个函数没有参数。 1216 | 1217 | """ 1218 | pass 1219 | 1220 | 1221 | def onTimer(self, timerHandle, userData): 1222 | """ 1223 | 功能说明: 1224 | 1225 | 这个函数当一个与此实体关联的定时器触发的时候被调用。一个定时器可以使用Base.addTimer函数添加。 1226 | 1227 | @param timerHandle:定时器的id。 1228 | @param userData:传进Base.addTimer的integer用户数据。 1229 | 1230 | """ 1231 | pass 1232 | 1233 | 1234 | def onWriteToDB(self, cellData): 1235 | """ 1236 | 功能说明: 1237 | 1238 | 如果这个函数在脚本中有实现,这个函数在实体数据将要写进数据库的时候被调用。 1239 | 1240 | 需要注意的是在该回调里调用writeToDB会导致无限循环。 1241 | @param cellData:包含将要存进数据库的cell属性。 cellData是一个字典。 1242 | 1243 | """ 1244 | pass 1245 | 1246 | class ClientAddrObject(object): 1247 | pass 1248 | 1249 | 1250 | class Proxy(Base): 1251 | 1252 | #------------------------------KBEngine.Proxy的成员属性-------------------------------------------- 1253 | __ACCOUNT_NAME__="" 1254 | """ 1255 | 说明: 1256 | 如果proxy是帐号则可以访问__ACCOUNT_NAME__得到帐号名。 1257 | """ 1258 | 1259 | __ACCOUNT_PASSWORD__="" 1260 | """ 1261 | 说明: 1262 | 如果proxy是帐号则可以访问__ACCOUNT_PASSWORD__得到帐号MD5密码。 1263 | """ 1264 | 1265 | clientAddr=ClientAddrObject() 1266 | 1267 | #entitiesEnabled似乎应该是只读的吧 1268 | 1269 | #hasClient似乎应该是只读的吧 1270 | 1271 | #roundTripTime这个是不是应该也是只读的呢 1272 | 1273 | #timeSinceHeardFromClient这个是不是应该也是只读的呢 1274 | 1275 | __entitiesEnabled=False 1276 | 1277 | @property 1278 | def entitiesEnabled(self): 1279 | """ 1280 | 实体是否已经可用。在实体可用之前脚本不能与客户端进行通讯。 1281 | """ 1282 | return self.__entitiesEnabled 1283 | 1284 | __hasClient=False 1285 | 1286 | @property 1287 | def hasClient(self): 1288 | """ 1289 | Proxy是否绑定了一个客户端连接。 1290 | """ 1291 | return self.__hasClient 1292 | 1293 | __roundTripTime=0.0 1294 | 1295 | @property 1296 | def roundTripTime(self): 1297 | """ 1298 | 在一段时间内服务器与这个Proxy绑定的客户端通讯平均往返时间。这个属性只在Linux下生效。 1299 | @return: 1300 | """ 1301 | return self.__roundTripTime 1302 | 1303 | __timeSinceHeardFromClient=0.0 1304 | 1305 | 1306 | @property 1307 | def timeSinceHeardFromClient(self): 1308 | """ 1309 | 最后一次收到客户端数据包时到目前为止所过去的时间(秒)。 1310 | @return: 1311 | """ 1312 | return self.__timeSinceHeardFromClient 1313 | 1314 | 1315 | 1316 | 1317 | 1318 | 1319 | 1320 | 1321 | 1322 | 1323 | 1324 | def getClientType(self): 1325 | """ 1326 | 功能说明: 1327 | 1328 | 这个函数返回客户端类型。 1329 | @return: UNKNOWN_CLIENT_COMPONENT_TYPE = 0, 1330 | CLIENT_TYPE_MOBILE = 1, // 手机类 1331 | CLIENT_TYPE_PC = 2, // pc, 一般都是exe客户端 1332 | CLIENT_TYPE_BROWSER = 3, // web应用, html5,flash 1333 | CLIENT_TYPE_BOTS = 4, // bots 1334 | CLIENT_TYPE_END = 5 // end 1335 | 1336 | """ 1337 | pass 1338 | 1339 | 1340 | def giveClientTo(self, proxy): 1341 | """ 1342 | 功能说明: 1343 | 1344 | 将客户端的控制器转交给另一个Proxy,当前的Proxy必须有一个客户端而目标Proxy则必须没有关联客户端,否则将会提示错误。 1345 | 参看: Proxy.onGiveClientToFailure 1346 | 1347 | 1348 | @param proxy:控制权将转交给这个实体。 1349 | 1350 | """ 1351 | pass 1352 | 1353 | 1354 | def streamFileToClient(self, resourceName, desc="", id=-1): 1355 | """ 1356 | 功能说明: 1357 | 1358 | 这个函数类似于streamStringToClient(),将一个资源文件发送给客户端。发送过程在不同的线程上操作,因此不会危及主线程。 1359 | 参看: Proxy.onStreamComplete 1360 | 1361 | 1362 | 1363 | 1364 | @param resourceName:要发送的资源名称,包含路径。 1365 | @param desc:一个可选的字符串,发送给客户端的资源描述。 1366 | @param id:一个16位的id,它的值完全取决于调用者。如果传入-1系统将会在队列里面选择一个没有在用的id。可以在客户端根据这个id做资源判断。 1367 | @return:与这个下载关联的id。 1368 | """ 1369 | pass 1370 | 1371 | 1372 | def streamStringToClient(self, data, desc="", id=-1): 1373 | """ 1374 | 功能说明: 1375 | 1376 | 发送一些数据到当前实体绑定的客户端。如果客户端端口则数据被清除,当客户端再次绑定到实体的时候才可调用这个函数。16位的id完全取决于调用者。 1377 | 如果调用者没有指定这个ID则系统会分配一个未用过的id。可以在客户端根据这个id做资源判断。 1378 | 1379 | 你可以在Proxy的派生类中定义回调函数(onStreamComplete),所有数据成功发送给客户端时或下载失败时会调用这个回调函数。 1380 | 1381 | 参看:Proxy.onStreamComplete与客户端实体Entity.onStreamDataStarted和 Entity.onStreamDataRecv还有Entity.onStreamDataCompleted。 1382 | 1383 | @param data:要发送的字符串。 1384 | @param desc:一个可选的字符串,发送给客户端的描述。 1385 | @param id:一个16位的id,它的值完全取决于调用者。如果传入-1系统将会在队列里面选择一个没有在用的id。 1386 | @return:与这个下载关联的id。 1387 | """ 1388 | pass 1389 | 1390 | 1391 | # Proxy类的回调函数 1392 | 1393 | def onClientDeath(self): 1394 | """ 1395 | 如果在脚本中实现了此回调,这个方法将在客户端断开连接时被调用。 这个方法没有参数。 1396 | 1397 | 1398 | """ 1399 | pass 1400 | 1401 | 1402 | def onClientGetCell(self): 1403 | """ 1404 | 如果在脚本中实现了此回调,当客户端能够调用实体的cell属性时,该回调被调用。 1405 | 1406 | """ 1407 | 1408 | pass 1409 | 1410 | 1411 | def onEntitiesEnabled(self): 1412 | """ 1413 | 如果在脚本中实现了此回调,当实体可用时( 各种初始化完毕并且可以与客户端通讯 )该回调被调用。 这个方法没有参数。 1414 | 1415 | """ 1416 | pass 1417 | 1418 | 1419 | def onGiveClientToFailure(self): 1420 | """ 1421 | 如果在脚本中实现了此回调,当实体调用giveClientTo失败时,该回调被调用。这个方法没有参数。 1422 | 1423 | """ 1424 | pass 1425 | 1426 | 1427 | def onLogOnAttempt(self, ip, port, password): 1428 | """ 1429 | 如果在脚本中实现了此回调,这个函数在客户端尝试使用当前账号实体进行登录时触发回调。 1430 | 这种情况通常是实体存在于内存中处于有效状态,最明显的例子是用户A使用此账号登录了,用户B使用同一账号进行登录,此时回调触发。 1431 | 1432 | 这个回调函数可以返回如下常量值: 1433 | KBEngine.LOG_ON_ACCEPT:允许新的客户端与实体进行绑定,如果实体已经绑定了一个客户端,之前的客户端将被踢出。 1434 | KBEngine.LOG_ON_REJECT:拒绝新的客户端与实体绑定。 1435 | KBEngine.LOG_ON_WAIT_FOR_DESTROY:等待实体销毁后再进行客户端绑定。 1436 | 1437 | @param ip:尝试登录的客户端IP地址。 1438 | @param port:尝试登录的客户端连接的端口。 1439 | @param password:用户登录时使用的MD5密码。 1440 | """ 1441 | pass 1442 | 1443 | 1444 | def onStreamComplete(self, id, success): 1445 | """ 1446 | 如果在脚本中实现了此回调,当用户使用Proxy.streamStringToClient()或Proxy.streamFileToClient()完成时,该回调被调用。 1447 | @param id:与下载关联的id。 1448 | @param success:成功与否。 1449 | @return: 1450 | """ 1451 | pass 1452 | -------------------------------------------------------------------------------- /tips/BaseApp/__init__.py: -------------------------------------------------------------------------------- 1 | __author__ = 'd7' 2 | -------------------------------------------------------------------------------- /tips/CellApp/KBEngine.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | class EntitiesObject(object): 4 | pass 5 | 6 | #--------------KBEngine模块的成员属性-------------------------------- 7 | 8 | LOG_TYPE_DBG=0 9 | LOG_TYPE_ERR=0 10 | LOG_TYPE_INFO=0 11 | LOG_TYPE_NORMAL=0 12 | LOG_TYPE_WAR=0 13 | #该属性不确定这样定义 14 | NEXT_ONLY=2 15 | 16 | """ 17 | cellApp为类字典对象,下面创建了一个空的字典 18 | """ 19 | cellAppData={} 20 | 21 | #该属性不确定这样定义 22 | component="" 23 | """__component="" 24 | 25 | def component(): 26 | return __component 27 | 这样定义语法提示会有问题 28 | """ 29 | 30 | #该属性不确定这样定义 31 | entities=EntitiesObject() 32 | """ 33 | 说明: 34 | 35 | entities是一个字典对象,包含当前进程上所有的实体。 36 | 调试泄露的实体(调用过destroy却没有释放内存的实体,通常是由于被引用导致无法释放): 37 | 38 | >>> KBEngine.entities.garbages.items() 39 | [(1025, Avatar object at 0x7f92431ceae8.)] 40 | 41 | >>> e = _[0][1] 42 | >>> import gc 43 | >>> gc.get_referents(e) 44 | [{'spacesIsOk': True, 'bootstrapIdx': 1}, ] 45 | 46 | 47 | 调试泄露的KBEngine封装的Python对象: 48 | KBEngine.debugTracing 49 | 类型: Entities 50 | """ 51 | 52 | globalData={} 53 | 54 | #GlobalDataClient 等文档 55 | 56 | 57 | 58 | #----------------KBEngine模块的成员函数-------------------------------------- 59 | def addSpaceGeometryMapping(spaceID, mapper, path, shouldLoadOnServer): 60 | """ 61 | 功能说明: 62 | 63 | 关联一个给定空间的几何映射,函数调用之后服务端和客户端都会加载相应的几何体数据。 64 | 65 | 66 | 在服务端上,从给定目录里加载所有的几何数据到指定的空间。这些数据可能被分成很多区块,不同区块是异步加载的,当所有的几何数据加载完成的时候下面的通知方法会被调用: 67 | def onAllSpaceGeometryLoaded( self, spaceID, mappingName ): 68 | 69 | 70 | 服务端仅加载场景的几何数据提供给导航和碰撞功能使用,客户端除了几何数据外还会加载纹理等数据。 71 | 3D场景当前默认使用的是recastnavigation插件所导出的数据,2D场景当前默认使用的是MapEditor编辑器导出的数据。 72 | 73 | 有一种可能会导致onAllSpaceGeometryLoaded()不被调用,就是如果在某一个时刻多个CellApp同时调用这个方法来添加几何到相同的空间的时候CellAppMgr崩溃了。 74 | 75 | @param spaceID:uint32,空间的ID,指定在哪个空间操作 76 | @param mapper:目前填None 77 | @param path:包含几何数据的目录路径 78 | @param shouldLoadOnServer:可选的boolean参数,指定是否在服务端上加载几何。默认为True 79 | 80 | """ 81 | pass 82 | 83 | 84 | def addWatcher(path, getFunction, setFunction): 85 | """ 86 | 功能说明: 87 | 88 | 与调试监视系统交互,允许用户向监视系统注册一个监视变量。 89 | 90 | 例: 91 | 92 | 93 | 94 | 这个函数添加一个监视变量在"scripts/players"监视路径之下。函数countPlayers在观察者观察时被调用。 95 | 96 | @param path: 创建监视的路径。 97 | @param getFunction: 监视变量的值类型。参考: 基本类型 98 | @param setFunction: 这个函数当观察者检索该变量时调用。这个函数不带参数返回一个代表监视变量的值。 99 | 100 | 101 | """ 102 | pass 103 | def address( ): 104 | """ 105 | 功能说明: 106 | 107 | 返回内部网络接口的地址。 108 | 109 | 110 | """ 111 | pass 112 | 113 | 114 | def Blob(): 115 | """ 116 | 功能说明: 117 | 118 | 返回一个新的blob对象。 119 | 120 | Blob对象存储的是二进制信息,提供这个类型是为了让用户能够方便的序列化与反序列化Python基本类型同时能与KBEngine底层序列化规则相同。 121 | 122 | 123 | 例如:你可以使用这个对象构造一个KBEngine能解析的网络数据包。 124 | 125 | 用法: 126 | >>> s = KBEngine.Blob() 127 | >>> s 128 | >>> b'' 129 | >>> s.append("UINT32", 1) 130 | >>> s.pop("UINT32") 131 | >>> 1 132 | 133 | 目前Blob能够支持的类型仅为基本数据类型。参考: 基本类型 134 | 135 | """ 136 | pass 137 | 138 | def createEntity(className, spaceID, position, direction, params ): 139 | 140 | """ 141 | 功能说明: 142 | 143 | createEntity在当前进程指定space中创建一个新的实体。 144 | 这个函数需要指定要创建的实体的类别,位置和方向,还可以选择性地设置实体的任意属性(属性在实体的.def文件里描述)。 145 | 146 | 例子: 147 | # 创建一个打开的门的实体与"thing"实体的位置一样 148 | direction = ( 0, 0, thing.yaw ) 149 | properties = { "open":1 } 150 | KBEngine.createEntity( "Door", thing.space, thing.position, direction, 151 | properties ) 152 | 153 | @param className:string,要实例化的类的名字。需要注意的是这必须是一个实体类,在/scripts/entities.xml文件里声明。 154 | @param spaceID:int32,要放置实体的空间的ID。 155 | @param position:由3个float组成的序列,指定新实体的出生点,在世界中的坐标。 156 | @param direction:由3个float组成的序列,指定新实体的初始朝向(roll, pitch, yaw),相对于世界坐标系。 157 | @param params:可选参数, 一个Python字典对象。如果一个指定的键是一个Entity属性,他的值会用来初始化这个Entity实体的属性。 158 | @param return:返回新实体。 159 | """ 160 | pass 161 | 162 | def debugTracing(): 163 | """ 164 | 功能说明: 165 | 166 | 输出当前KBEngine追踪的Python扩展对象计数器。 167 | 扩展对象包括:固定字典、固定数组、Entity、Mailbox... 168 | 在服务端正常关闭时如果计数器不为零,此时说明泄露已存在,日志将会输出错误信息。 169 | 170 | ERROR cellapp [0x0000cd64] [2014-11-12 00:38:07,300] - PyGC::debugTracing(): FixedArray : leaked(128) 171 | ERROR cellapp [0x0000cd64] [2014-11-12 00:38:07,300] - PyGC::debugTracing(): EntityMailbox : leaked(8) 172 | 173 | 174 | 175 | """ 176 | pass 177 | 178 | def delSpaceData( spaceID,key ): 179 | """ 180 | 功能说明: 181 | 182 | 删除指定key的space数据(如果space分割成多个部分,将进行同步删除)。 183 | space数据由用户通过setSpaceData设置。 184 | 185 | @param spaceID:int32,空间的ID。 186 | @param key:string,一个字符串关键字。 187 | """ 188 | pass 189 | 190 | def delWatcher( path ): 191 | 192 | """ 193 | 功能说明: 194 | 195 | 与调试监视系统交互,允许用户在脚本删除监视的变量。 196 | 197 | @param path:要删除的变量的路径。 198 | 199 | 200 | """ 201 | pass 202 | 203 | 204 | def executeRawDatabaseCommand(command, callback, threadID): 205 | """ 206 | 功能说明: 207 | 208 | 这个脚本函数在数据库上执行原始数据库命令,该命令将直接由相关数据库进行解析。 209 | 210 | 请注意使用该函数修改实体数据可能不生效,因为如果实体已经检出,被修改过的实体数据将仍会被实体存档而导致覆盖。 211 | 强烈不推荐这个函数用于读取或修改实体数据。 212 | 213 | @param command:这个数据库命令将会因为不同数据库配置方案而不同。对于方案为MySQL数据库它是一个SQL查询语句。 214 | @param callback:可选参数,带有命令执行结果的回调对象(比如说是一个函数)。这个回调带有3个参数:结果集合,影响的行数与错误信息。 215 | 216 | 这个结果集合参数是一个行列表。每一行是一个包含字段值的字符串列表。命令执行没有返回结果集合(比如说是DELETE命令),或者 217 | 命令执行有错误时这个结果集合为None。 218 | 219 | 这个数字是命令执行受影响的行数。这个参数只和不返回结果结合的命令(如DELETE)相关。 220 | 如果有结果集合返回或者命令执行有错误时这个参数为None。 221 | 222 | 命令执行有错误时这个错误信息参数是一个描述错误的字符串。命令执行没有发生错误时这个参数为None。 223 | @param threadID:int32,可选参数,指定一个线程来处理本条命令。用户可以通过这个参数控制某一类命令的执行先后顺序(dbmgr是多线程处理的),默认是不指定,如果threadID是实体的ID, 224 | 那么将加入到该实体的存档队列中由线程逐条写入。 225 | """ 226 | pass 227 | 228 | def genUUID64( ): 229 | """ 230 | 功能说明: 231 | 232 | 该函数生成一个64位的唯一ID。 233 | 注意:这个函数依赖于Baseapps服务进程启动参数cid与globalorder,请正确设置启动参数保持唯一性。 234 | 235 | 用途: 236 | 多个服务进程上产生唯一物品ID并且在合服时不会产生冲突。 237 | 多个服务进程上产生一个房间ID,不需要进行唯一性校验。 238 | 239 | 240 | @return:返回一个64位的integer。 241 | """ 242 | pass 243 | 244 | def getResFullPath( res ): 245 | """ 246 | 功能说明: 247 | 248 | 获取资源的绝对路径。 249 | 注意:资源必须在KBE_RES_PATH之下才可以访问到。 250 | 251 | @param res:string,资源的相对路径。 252 | @return:string,资源的绝对路径。 253 | 254 | 255 | """ 256 | 257 | pass 258 | 259 | def getSpaceData( spaceID, key ): 260 | """ 261 | 功能说明: 262 | 263 | 获取指定key的space数据。 264 | space数据由用户通过setSpaceData设置 265 | 266 | @param spaceID:int32,空间的ID。 267 | @param key:string,一个字符串关键字。 268 | @return:string,指定key的字符串数据。 269 | """ 270 | pass 271 | 272 | def getSpaceGeometryMapping( spaceID ): 273 | """ 274 | 功能说明: 275 | 276 | 返回一个指定空间的几何映射名称。 277 | @param spaceID:要查询的空间的id。 278 | @return:string,几何映射名称。 279 | """ 280 | pass 281 | 282 | def getWatcher( path ): 283 | """ 284 | 功能说明: 285 | 286 | 从KBEngine调试系统中获取一个监视变量的值。 287 | 288 | 例子:在baseapp1的Python命令行输入: 289 | >>>KBEngine.getWatcher("/root/stats/runningTime") 290 | 12673648533 291 | 292 | >>>KBEngine.getWatcher("/root/scripts/players") 293 | 32133 294 | 295 | @param path:string,该变量的绝对路径包括变量名(可以在GUIConsole的watcher页查看)。 296 | @return:该变量的值。 297 | 298 | 299 | """ 300 | pass 301 | 302 | def getWatcherDir( path ): 303 | """ 304 | 功能说明: 305 | 306 | 从KBEngine调试系统中获取一个监视目录下的元素列表(目录、变量名)。 307 | 308 | 例子:在baseapp1的Python命令行输入: 309 | >>>KBEngine.getWatcher("/root") 310 | ('stats', 'objectPools', 'network', 'syspaths', 'ThreadPool', 'cprofiles', 'scripts', 'numProxices', 'componentID', 'componentType', 'uid', 'numClients', 'globalOrder', 'username', 'load', 'gametime', 'entitiesSize', 'groupOrder') 311 | 312 | @param path:string,该变量的绝对路径(可以在GUIConsole的watcher页查看)。 313 | @return:监视目录下的元素列表(目录、变量名)。 314 | """ 315 | pass 316 | 317 | def hasRes( res ): 318 | """ 319 | 功能说明: 320 | 321 | 使用这个接口可以判断一个相对路径的资源是否存在。 322 | 注意:资源必须在KBE_RES_PATH之下才可以访问到。 323 | 324 | 例子: 325 | 326 | >>>KBEngine.hasRes("scripts/entities.xml") 327 | True 328 | 329 | @param res:string,资源的相对路径。 330 | @return:BOOL, 存在返回True,否则返回False。 331 | 332 | """ 333 | pass 334 | 335 | def isShuttingDown( ): 336 | """ 337 | 功能说明: 338 | 339 | 返回服务端是否正在关闭中。在onBaseAppShuttingDown回调函数被调用后,这个函数返回True。 340 | @return:系统正在关闭返回True,否则返回False。 341 | 342 | 343 | """ 344 | pass 345 | 346 | def listPathRes( path, extension ): 347 | """ 348 | 功能说明: 349 | 350 | 获得一个资源目录下的资源列表。 351 | 注意:资源必须在KBE_RES_PATH之下才可以访问到。 352 | 353 | 例子: 354 | 355 | >>>KBEngine.listPathRes("scripts/cell/interfaces") 356 | ('/home/kbe/kbengine/demo/res/scripts/cell/interfaces/AI.py', '/home/kbe/kbengine/demo/res/scripts/cell/interfaces/新建文本文档.txt') 357 | 358 | >>>KBEngine.listPathRes("scripts/cell/interfaces", "txt") 359 | ('/home/kbe/kbengine/demo/res/scripts/cell/interfaces/新建文本文档.txt') 360 | 361 | >>>KBEngine.listPathRes("scripts/cell/interfaces", "txt|py") 362 | ('/home/kbe/kbengine/demo/res/scripts/cell/interfaces/AI.py', '/home/kbe/kbengine/demo/res/scripts/cell/interfaces/新建文本文档.txt') 363 | 364 | >>>KBEngine.listPathRes("scripts/cell/interfaces", ("txt", "py")) 365 | ('/home/kbe/kbengine/demo/res/scripts/cell/interfaces/AI.py', '/home/kbe/kbengine/demo/res/scripts/cell/interfaces/新建文本文档.txt') 366 | 367 | @param path:string,资源的相对路径。 368 | @param extension:string,可选参数,扩展名。 369 | 370 | 371 | @return:Tuple, 资源列表。 372 | """ 373 | pass 374 | 375 | def matchPath( res ): 376 | """ 377 | 功能说明: 378 | 379 | 使用相对路径的资源获得资源的绝对路径。 380 | 注意:资源必须在KBE_RES_PATH之下才可以访问到。 381 | 382 | 例子: 383 | 384 | >>>KBEngine.matchPath("scripts/entities.xml") 385 | '/home/kbe/kbengine/demo/res/scripts/entities.xml' 386 | 387 | @param res:string,资源的相对路径(包括资源名称)。 388 | @return:string, 资源的绝对路径。 389 | """ 390 | pass 391 | 392 | def open( res, mode ): 393 | """ 394 | 功能说明: 395 | 396 | 使用这个接口可以使用相对路径来打开相关资源。注意:资源必须在KBE_RES_PATH之下才可以访问到。 397 | @param res:string,资源的相对路径。 398 | @param mode:string,文件操作模式: 399 | w 以写方式打开, 400 | a 以追加模式打开 (从 EOF 开始, 必要时创建新文件) 401 | r+ 以读写模式打开 402 | w+ 以读写模式打开 (参见 w ) 403 | a+ 以读写模式打开 (参见 a ) 404 | rb 以二进制读模式打开 405 | wb 以二进制写模式打开 (参见 w ) 406 | ab 以二进制追加模式打开 (参见 a ) 407 | rb+ 以二进制读写模式打开 (参见 r+ ) 408 | wb+ 以二进制读写模式打开 (参见 w+ ) 409 | ab+ 以二进制读写模式打开 (参见 a+ ) 410 | 411 | @return: 412 | """ 413 | pass 414 | 415 | def publish( ): 416 | """ 417 | 功能说明: 418 | 419 | 这个接口返回当前服务端发行模式。 420 | 421 | @return:int8,0:debug,1:release,其它可自定义。 422 | """ 423 | pass 424 | 425 | def reloadScript( fullReload ): 426 | """ 427 | 功能说明: 428 | 429 | 重新加载与实体和自定义数据类型相关的Python模块。当前实体类会设置为新加载的类。这个方法应该只用于开发模式,对于产品模式不合适。下面几点应该注意: 430 | 431 | 1)重载脚本仅仅能在Cellapp上执行, 用户应该确保所有的服务端组件加载完成。 432 | 433 | 2)自定义类型在脚本重载后应该确保内存中已经实例化的对象也被更新,下面是一个例子: 434 | 435 | 436 | for e in KBEngine.entities.values(): 437 | if type( e ) is Avatar.Avatar: 438 | e.customData.__class__ = CustomClass 439 | 440 | 当这个方法完成时 KBEngine.onInit( True ) 被调用。 441 | 442 | @param fullReload:可选的boolean参数,指定是否同时重新加载实体定义。如果这个参数为False,则实体定义不会被重新加载。默认为True。 443 | @return:重新加载成功返回True,否则返回False。 444 | 445 | 446 | """ 447 | pass 448 | 449 | def scriptLogType( logType ): 450 | 451 | """ 452 | 功能说明: 453 | 454 | 设置当前Python.print输出的信息类型(参考: KBEngine.LOG_TYPE_*)。 455 | 456 | @param logType: 457 | @return: 458 | """ 459 | pass 460 | 461 | def setSpaceData( spaceID, key, value ): 462 | 463 | """ 464 | 功能说明: 465 | 466 | 设置指定key的space数据。 467 | space数据可以通过getSpaceData获取。 468 | 469 | @param spaceID:int32,空间的ID。 470 | @param key:string,一个字符串关键字。 471 | @param value:string,字符串值。 472 | @return: 473 | """ 474 | pass 475 | 476 | def time( ): 477 | 478 | """ 479 | 功能说明: 480 | 481 | 这个方法返回当前游戏的时间(周期数)。 482 | @return:uint32,当前游戏的时间,这里指周期数,周期受频率影响,频率由配置文件kbengine.xml或者kbengine_defs.xml->gameUpdateHertz决定。 483 | """ 484 | pass 485 | 486 | 487 | 488 | 489 | #回调函数 490 | 491 | 492 | def onCellAppData( key, value ): 493 | 494 | """ 495 | 功能说明: 496 | 497 | KBEngine.cellAppData有改变时回调此函数。 498 | 注意:该回调接口必须实现在入口模块(kbengine_defs.xml->entryScriptFile)中。 499 | @param key:被改变数据的键。 500 | @param value:被改变数据的值。 501 | @return: 502 | """ 503 | pass 504 | 505 | def onCellAppDataDel( key ): 506 | 507 | """ 508 | 功能说明: 509 | 510 | KBEngine.cellAppData有删除的时候回调此函数。 511 | 注意:该回调接口必须实现在入口模块(kbengine_defs.xml->entryScriptFile)中。 512 | 513 | @param key:被删除数据的键。 514 | @return: 515 | """ 516 | pass 517 | 518 | def onGlobalData( key, value ): 519 | 520 | """ 521 | 功能说明: 522 | 523 | KBEngine.globalData有改变的时候回调此函数。 524 | 注意:该回调接口必须实现在入口模块(kbengine_defs.xml->entryScriptFile)中。 525 | @param key:被改变数据的键。 526 | @param value:被改变数据的值。 527 | @return: 528 | """ 529 | pass 530 | 531 | def onGlobalDataDel( key ): 532 | 533 | """ 534 | 功能说明: 535 | 536 | KBEngine.globalData有删除的时候回调此函数。 537 | 注意:该回调接口必须实现在入口模块(kbengine_defs.xml->entryScriptFile)中。 538 | 539 | @param key:被删除数据的键。 540 | @return: 541 | """ 542 | pass 543 | 544 | 545 | def onInit( isReload ): 546 | 547 | """ 548 | 549 | 功能说明: 550 | 551 | 当引擎启动后初始化完所有的脚本后这个接口被调用。 552 | 注意:该回调接口必须实现在入口模块(kbengine_defs.xml->entryScriptFile)中。 553 | 554 | @param isReload:bool,是否是被重写加载脚本后触发的。 555 | @return: 556 | """ 557 | pass 558 | 559 | def onSpaceData( spaceID, key, value ): 560 | """ 561 | 功能说明: 562 | 563 | 当space数据有改变的时候被调用。 564 | space数据由用户通过setSpaceData设置。 565 | @param spaceID:空间的ID。 566 | @param key:被改变数据的键。 567 | @param value: 被改变数据的值。 568 | @return: 569 | """ 570 | pass 571 | 572 | def onSpaceGeometryLoaded( spaceID, mapping ): 573 | """ 574 | 功能说明: 575 | 576 | 空间所需求的网格碰撞等数据加载完毕。 577 | 由用户通过addSpaceGeometryMapping设置。 578 | @param spaceID:空间的ID。 579 | @param mapping:网格碰撞数据的映射值。 580 | @return: 581 | """ 582 | pass 583 | 584 | def onAllSpaceGeometryLoaded( spaceID, isBootstrap, mapping ): 585 | 586 | """ 587 | 功能说明: 588 | 589 | 空间所需求的网格碰撞等数据全部加载完毕。 590 | 由用户通过addSpaceGeometryMapping设置。 591 | @param spaceID:空间的ID。 592 | @param isBootstrap:如果一个空间被分割由多个cell共同负载,那么isBootstrap描述的是是否为加载请求的发起cell。 593 | @param mapping:网格碰撞数据的映射值。 594 | @return: 595 | """ 596 | pass 597 | 598 | class AllClientsObject(object): 599 | pass 600 | 601 | class BaseObject(object): 602 | pass 603 | 604 | class ClientObject(object): 605 | pass 606 | 607 | class OtherClientsObject(object): 608 | pass 609 | 610 | class Vector3Object(object): 611 | pass 612 | 613 | 614 | 615 | class Entity: 616 | """ 617 | cell进程脚本一般继承KBEngine.Entity 618 | """ 619 | 620 | #-------------cellapp-KBEngine.Entity类的成员属性------------------------------------------- 621 | #allClients是不是一个这样定义,不确定 622 | __allClients=AllClientsObject() 623 | 624 | @property 625 | def allClients(self): 626 | return self.__allClients 627 | 628 | #base属性是不是一个这样定义,不确定 629 | __base=BaseObject() 630 | 631 | 632 | @property 633 | def base(self): 634 | return self.__base 635 | 636 | 637 | __className="" 638 | 639 | @property 640 | def className(self): 641 | return self.__className 642 | 643 | #该属性是不是一个这样定义,不确定 644 | __client=ClientObject() 645 | 646 | @property 647 | def client(self): 648 | return self.__client 649 | 650 | 651 | 652 | # Vector3应该和kbengine\kbe\src\lib\pyscript\vector3.hpp有关 653 | #该属性是不是一个这样定义,不确定 654 | direction=Vector3Object() 655 | """ 656 | 这个属性描述的是Entity在世界空间中的朝向,用户可以改变这个属性,数据会同步到客户端。 657 | 类型: Vector3, 其中包含(roll, pitch, yaw),以弧度表示。 658 | """ 659 | 660 | 661 | 662 | __hasWitness=False 663 | 664 | @property 665 | def hasWitness(self): 666 | """ 667 | 这个只读属性如果为True,表示实体已经绑定了一个Witness, 668 | 绑定了Witness的实体则客户端可以通过实体获得实体AOI范围内的信息。否则为False。 669 | 类型: 只读的, bool 670 | 671 | """ 672 | return self.__hasWitness 673 | 674 | __id=0 675 | 676 | @property 677 | def id(self): 678 | """ 679 | id是Entity的对象id。这个id是一个整型,在base,cell和client相关联的实体之间是相同的。 680 | 这个属性是只读的。 681 | 类型: 只读的,int32 682 | """ 683 | return self.__id 684 | 685 | __isDestroyed=False 686 | 687 | @property 688 | def isDestroyed(self): 689 | """ 690 | 如果这个属性的值为True,Entity则已经被销毁了。 691 | 类型: 只读的, bool 692 | """ 693 | return self.__isDestroyed 694 | 695 | __isOnGround=False 696 | 697 | @property 698 | def isOnGround(self): 699 | """ 700 | 如果这个属性的值为True,Entity在地面上,否则为False。 701 | 类型: 只读的, bool 702 | """ 703 | return self.__isDestroyed 704 | 705 | __isWitnessed=False 706 | 707 | @property 708 | def isWitnessed(self): 709 | """ 710 | 如果当前实体进入了另一个绑定了Witness的实体的AOI范围 711 | (也可以理解为一个实体被观察者观察到了, 这个属性值为True,否则为False。 712 | 参考: 713 | Entity.onWitnessed 714 | 类型: 只读的, bool 715 | """ 716 | return self.__isWitnessed 717 | 718 | #该属性是不是一个这样定义,不确定 719 | __otherClients=OtherClientsObject() 720 | 721 | @property 722 | def otherClients(self): 723 | """ 724 | otherClients 725 | 通过这个属性调用实体的客户端远程方法, 726 | 引擎会将这个消息广播给实体AOI范围内所有的其他绑定了客户端的实体 727 | (不包括自己的客户端,绑定了客户端的实体通常为玩家)。 728 | 729 | 730 | 例子: 731 | avatar的AOI范围内有玩家A和玩家B以及怪物C。 732 | avatar.otherClients.attack(monsterID,skillID, damage) 733 | 734 | 此时,玩家A与玩家B的客户端都会调用到该实体attack方法,在他们的客户端可以调用指定技能的攻击动作做表现。 735 | 其他参考: Entity.clientEntity 736 | Entity.otherClients 737 | 该属性应该是只读的吧 738 | """ 739 | return self.__otherClients 740 | 741 | __pitch=0.0 742 | 743 | 744 | 745 | 746 | @property 747 | def pitch(self): 748 | """ 749 | 实体在世界空间中的俯仰角,绕X轴旋转。 750 | 这个属性也可以通过direction属性访问。 751 | Type: Float,只读属性。 752 | """ 753 | return self.__pitch 754 | 755 | 756 | #该属性是不是一个这样定义,不确定 757 | position=Vector3Object() 758 | """ 759 | 这个实体在世界空间中的坐标(x, y, z),这个属性可以被用户改变,改变后会同步到客户端。需要注意的是,不要引用这个属性,引用这个属性很有可能错误的修改了实体的真实坐标。 760 | 761 | 例子: 762 | self.position.y = 10.0 763 | 764 | 765 | 766 | 如果你想拷贝这个属性值可以使用如下方式: 767 | 768 | import Math 769 | self.copyPosition = Math.Vector3( self.position ) 770 | 771 | 类型: Vector3 772 | 773 | 774 | 775 | """ 776 | 777 | __roll=0.0 778 | 779 | @property 780 | def roll(self): 781 | """ 782 | 实体在世界空间中的横滚角,绕Z轴旋转。 783 | 这个属性也可以通过direction属性访问。 784 | Type: Float,只读属性。 785 | """ 786 | return self.__roll 787 | 788 | __spaceID=0 789 | 790 | @property 791 | def spaceID(self): 792 | """ 793 | 这个属性是实体所在的空间的ID,cell与客户端这个值都保持一致。 794 | 类型: 只读的,Integer。 795 | """ 796 | return self.__spaceID 797 | 798 | topSpeed=0.0 799 | """ 800 | 实体的最大xz轴移动速度,这个属性通常要比实际移动速度要大一些, 801 | 服务端通过这个属性检查客户端的移动合法性,如果移动距离超出速度限制则被强制拉回上一个坐标位置。 802 | 803 | 其他参考: Entity.topSpeedY 804 | 类型: float 805 | """ 806 | 807 | topSpeedY=0.0 808 | """ 809 | 实体的最大y轴移动速度,这个属性通常要比实际移动速度要大一些, 810 | 服务端通过这个属性检查客户端的移动合法性,如果移动距离超出速度限制则被强制拉回上一个坐标位置。 811 | 其他参考: Entity.topSpeed 812 | 类型: float 813 | """ 814 | 815 | volatileInfo=(0.0,0.0,0.0,0.0) 816 | """ 817 | 这个属性指定Entity的易变类数据同步到客户端的策略。 818 | 易变类数据包括实体的坐标position和实体的朝向direction,易变类数据由于极易改变的特性,引擎底层使用了一套优化的方案将其同步到客户端。 819 | 这个属性是四个float的序列(position,yaw,pitch,roll)代表距离值,当一个实体靠近当前实体达到距离则服务端向其同步相关数据。 820 | 821 | 822 | 用户也可以在.def制定不同实体的同步策略: 823 | 824 | 825 | 826 | 827 | 20 828 | 829 | 830 | 类型: sequence,(类型应该是python序列中的元组), 四个浮点数(float, float, float, float) 831 | """ 832 | 833 | __yaw=0.0 834 | 835 | @property 836 | def yaw(self): 837 | """ 838 | 实体在世界空间中的偏航角,绕Y轴旋转。 839 | 这个属性也可以通过direction属性访问。 840 | Type: Float,只读属性。 841 | """ 842 | return self.__yaw 843 | 844 | 845 | 846 | 847 | 848 | 849 | 850 | 851 | 852 | 853 | 854 | 855 | 856 | 857 | 858 | 859 | 860 | 861 | 862 | 863 | 864 | 865 | 866 | 867 | 868 | 869 | 870 | 871 | 872 | def addProximity( self, rangeXZ, rangeY, userArg ): 873 | """ 874 | 功能说明: 875 | 876 | 创建一个范围触发器,当有其它实体进入或离开这个触发器区域的时候会通知这个Entity。这个区域是一个方形(为了效率)。如果 877 | 其它实体在x轴和z轴上均在给定的距离里面,则实体被视为在这个范围里面。这个Entity通过onEnterTrap和onLeaveTrap函数被 878 | 通知,这两个函数可以如下定义: 879 | 880 | 881 | def onEnterTrap( self, entityEntering, rangeXZ, rangeY, controllerID, userArg = 0 ): 882 | def onLeaveTrap( self, entityLeaving, rangeXZ, rangeY, controllerID, userArg = 0 ): 883 | 884 | 885 | 886 | 由于这个范围触发器是一个控制器,使用Entity.cancel带上控制器ID来删除它。 887 | 888 | 需要注意的是回调有可能会立刻被触发,即使在addProximity()调用返回之前。 889 | 参看: Entity.cancel 890 | 891 | 892 | 893 | 894 | @param rangeXZ: float,给定触发器xz轴区域的大小,必须大于等于0。 895 | @param rangeY: float,给定触发器y轴高度,必须大于等于0。 896 | 需要注意的是,这个参数要生效必须开放kbengine_defs.xml->cellapp->coordinate_system->rangemgr_y 897 | 开放y轴管理会带来一些消耗,因为一些游戏大量的实体都在同一y轴高度或者在差不多水平线高度,此时碰撞变得非常密集。 898 | 3D太空类游戏或者小房间类实体较少的游戏比较适合开放此选项。 899 | @param userArg:是一个可选的整型,所有控制器共有。如果这个值不为0则传给回调函数。建议在回调原型里设置默认值为0。 900 | @return:返回创建控制器的id。 901 | 902 | 903 | """ 904 | pass 905 | 906 | def addTimer( self, start, interval=0.0, userData=0 ): 907 | """ 908 | 909 | 功能说明: 910 | 911 | 注册一个定时器,定时器由回调函数onTimer触发,回调函数将在"initialOffset"秒后被执行第1次,而后将每间隔"repeatOffset"秒执行1次,可设定一个用户参数"userArg"(仅限integer类型)。 912 | 913 | onTimer 函数必须在entity的cell部分被定义,且带有2个参数,第1个integer类型的是timer的id(可用于移除timer的"delTimer"函数),第2个是用户参数"userArg"。 914 | 915 | 例子: 916 | # 这里是使用addTimer的一个例子 917 | import KBEngine 918 | 919 | class MyCellEntity( KBEngine.Entity ): 920 | 921 | def __init__( self ): 922 | KBEngine.Entity.__init__( self ) 923 | 924 | # 增加一个定时器,5秒后执行第1次,而后每1秒执行1次,用户参数是9 925 | self.addTimer( 5, 1, 9 ) 926 | 927 | # 增加一个定时器,1秒后执行,用户参数缺省是0 928 | self.addTimer( 1 ) 929 | 930 | # Entity的定时器回调"onTimer"被调用 931 | def onTimer( self, id, userArg ): 932 | print "MyCellEntity.onTimer called: id %i, userArg: %i" % ( id, userArg ) 933 | # if 这是不断重复的定时器,当不再需要该定时器的时候,调用下面函数移除: 934 | # self.delTimer( id ) 935 | 936 | @param start: float,指定定时器从注册到第一次回调的时间间隔(秒)。 937 | @param interval:float,指定第一次回调执行后每次执行的时间间隔(秒)。必须用函数delTimer移除定时器,否则它会一直重复下去。值小于等于0将被忽略。 938 | @param userData:integer,指定底层回调"onTimer"时的userArg参数值。 939 | @return:integer,该函数返回timer的内部id,这个id可用于delTimer移除定时器。 940 | 941 | """ 942 | pass 943 | 944 | def cancel( self, controllerID ): 945 | """ 946 | 功能说明: 947 | 948 | 函数cancel停止一个控制器对Entity的影响。它只能在一个real实体上被调用。 949 | 950 | @param controllerID:controllerID是要取消的控制器的索引,它是一个整型。一个专用的控制器类型的字符串也可以作为它的类型。 951 | 例如,一次只有一个移动/导航控制器可以被激活,这可以用entity.cancel( "Movement" )取消。 952 | """ 953 | pass 954 | def clientEntity( self, destID ): 955 | 956 | """ 957 | 功能说明: 958 | 959 | 通过这个方法可以访问自己客户端(当前实体必须绑定了客户端)中某个实体的方法,只有在AOI范围内的实体才会同步到客户端。它只能在一个real实体上被调用。 960 | @param destID:目标实体的ID。 961 | 962 | """ 963 | pass 964 | def debugAOI( self ): 965 | """ 966 | 功能说明: 967 | 968 | debugAOI输出Entity的AOI的详细信息到cell的调试日志。一份AOI系统工作的描述可以在Entity类文档中找到。 969 | 970 | 一份样品信息如下: 971 | INFO cellapp [0x00001a1c] [2014-11-04 00:28:41,409] - Avatar::debugAOI: 100 size=4, Seen=4, Pending=0, aoiRadius=50.000, aoiHyst=5.000 972 | INFO cellapp [0x00001a1c] [2014-11-04 00:28:41,409] - Avatar::debugAOI: 100 Avatar(102), position(771.586.211.002.776.55), dist=0 973 | INFO cellapp [0x00001a1c] [2014-11-04 00:28:41,409] - Avatar::debugAOI: 100 Monster(1028), position(820.834.211.635.768.749), dist=49.8659 974 | INFO cellapp [0x00001a1c] [2014-11-04 00:28:41,409] - Avatar::debugAOI: 100 NPC(1025), position(784.024.210.95.782.273), dist=13.6915 975 | INFO cellapp [0x00001a1c] [2014-11-04 00:28:41,409] - Avatar::debugAOI: 100 Avatar(106), position(771.586.211.002.776.55), dist=0 976 | 977 | 信息的第一行告诉我们: 978 | 实体#1000的数据 979 | 有4个实体在它的AOI区域并且已经同步给客户端。 980 | 有0个实体在它的AOI区域,正在等待同步到客户端。 981 | AOI的半径是 50.000 982 | AOI的滞后区域向外延伸了5.000 983 | 984 | 985 | """ 986 | pass 987 | def delTimer( self, id ): 988 | """ 989 | 功能说明: 990 | 991 | 函数delTimer用于移除一个注册的定时器,移除后的定时器不再执行。 992 | 只执行1次的定时器在执行回调后自动移除,不必要使用delTimer移除。 993 | 如果delTimer函数使用一个无效的id(例如已经移除),将会产生错误。 994 | 995 | @param id:integer,它指定要移除的定时器id。 996 | 997 | """ 998 | pass 999 | def destroy( self ): 1000 | """ 1001 | 功能说明: 1002 | 1003 | 这个函数销毁它的本地Entity实例,如果实体在其他进程上存在ghost部分也会同时通知销毁。 1004 | 这个函数最好由实体自己调用,如果这个实体是一个ghost则会抛出一个异常。如果回调函数onDestroy()被实现则被调用。 1005 | 1006 | 1007 | """ 1008 | pass 1009 | def destroySpace( self ): 1010 | """ 1011 | 功能说明: 1012 | 1013 | 销毁这个实体所在的空间。 1014 | @return: 1015 | """ 1016 | pass 1017 | def entitiesInAOI( self ): 1018 | """ 1019 | 功能说明: 1020 | 1021 | 获得这个实体的AOI范围内的实体列表。 1022 | @return: 1023 | """ 1024 | pass 1025 | def entitiesInRange( self, range, entityType=None, position=None ): 1026 | 1027 | """ 1028 | 功能说明: 1029 | 1030 | 在给定的距离内搜索实体。这是一个球形的搜索,3个轴的距离都要测量。这可以找到在这个实体的AOI范围之外的实体,但不能找到其他cell的实体。 1031 | 1032 | 例子: 1033 | self.entitiesInRange( 100, 'Creature', (100, 0, 100) ) 1034 | 1035 | 搜索到‘Creature’类型的实体列表(‘Creature’的子类实例化的实体)。中心点是(100, 0, 100),搜索半径是100米。 1036 | [ e for e in self.entitiesInRange( 100, None, (100,0,100) ) if isinstance( e, BaseType ) ] 1037 | 1038 | 将给出一个来自‘BaseType’或‘BaseType’的子类实例化的实体列表。 1039 | @param range:围绕这个实体搜索的距离,float类型 1040 | @param entityType:一个可选的字符串参数,实体的类型名称,用于匹配实体。 1041 | 如果实体类型是一个有效的类名( 有效的实体类型在/scripts/entities.xml列出 ), 1042 | 则只有这个类型的实体会被返回,否则将这个范围的所有实体都返回。 1043 | @param position:一个可选的Vector3类型参数,作为搜索半径的中心, 默认以实体自身为中心。 1044 | 1045 | """ 1046 | pass 1047 | def isReal( self ): 1048 | 1049 | """ 1050 | 功能说明: 1051 | 1052 | 这个函数返回这个Entity是real的还是一个ghost的。 1053 | 1054 | 这个函数很少被用到但对调试很有用。 1055 | @return:bool, 如果是real实体返回True,否则返回False。 1056 | 1057 | 1058 | """ 1059 | pass 1060 | def moveToEntity( self, destEntityID, velocity, range, userData, faceMovement, moveVertically ): 1061 | 1062 | """ 1063 | 功能说明: 1064 | 1065 | 直线移动实体到另一个Entity位置。 1066 | 任何实体,在任意时刻只能有一个移动控制器,重复调用任何移动函数将终止之前的移动控制器。 1067 | 调用后函数将返回一个可以用于取消这次移动的控制器ID。 1068 | 1069 | 例如,Entity.cancel( movementID )。移动取消还可以调用Entity.cancel( "Movement" )。当移动被取消之后回调通知方法将不被调用。 1070 | 1071 | 1072 | def onMove( self, controllerId, userData ): 1073 | def onMoveFailure( self, controllerId, userData ): 1074 | 1075 | 参考: Entity.cancel 1076 | 1077 | 1078 | 1079 | 参数: destEntityID int,目标Entity的ID 1080 | velocity float,Entity移动的速度,单位m/s 1081 | range float,到达目标停止的范围 1082 | userData object,可选参数,回调通知被调用时其中userData参数将为此值。 1083 | faceMovement bool,可选参数,如果实体面向移动方向则为true(默认)。如果是其它机制则为false。 1084 | moveVertically bool,可选参数,设为True指移动为直线移动,设为False指贴着地面直线移动(默认为False)。 1085 | 1086 | 1087 | @param destEntityID:int,目标Entity的ID 1088 | @param velocity:float,Entity移动的速度,单位m/s 1089 | @param range:float,到达目标停止的范围 1090 | @param userData:object,可选参数,回调通知被调用时其中userData参数将为此值。 1091 | @param faceMovement:bool,可选参数,如果实体面向移动方向则为true(默认)。如果是其它机制则为false。 1092 | @param moveVertically:bool,可选参数,设为True指移动为直线移动,设为False指贴着地面直线移动(默认为False)。 1093 | @return:int,新创建的控制器ID。 1094 | 1095 | """ 1096 | pass 1097 | def moveToPoint( self, destination, velocity, userData, faceMovement, moveVertically ): 1098 | 1099 | """ 1100 | 功能说明: 1101 | 1102 | 直线移动Entity到给定的坐标点,成功或失败会调用回调函数。 1103 | 任何实体,在任意时刻只能有一个移动控制器,重复调用任何移动函数将终止之前的移动控制器。 1104 | 返回一个可以用于取消这次移动的控制器ID。 1105 | 1106 | 例如: 1107 | Entity.cancel( movementID )。移动取消还可以调用Entity.cancel( "Movement" )。当移动被取消之后通知方法将不被调用。 1108 | 1109 | 回调函数如下定义: 1110 | def onMove( self, controllerId, userData ): 1111 | def onMoveFailure( self, controllerId, userData ): 1112 | 1113 | 参看: Entity.cancel 1114 | 1115 | 1116 | 1117 | 1118 | @param destination:Vector3,Entity要移动到的目标位置点 1119 | @param velocity:float,Entity的移动速度,单位m/s 1120 | @param userData:object,传给通知函数的数据 1121 | @param faceMovement:bool,如果实体面向移动方向则为true(默认)。如果是其它机制则为false。 1122 | @param moveVertically:bool,设为true指移动为直线移动,设为false指贴着地面移动(默认为false)。 1123 | @return:int,新创建的控制器ID。 1124 | 1125 | """ 1126 | pass 1127 | def navigate( self, destination, velocity, maxMoveDistance, maxSearchDistance, faceMovement, girth, userData ): 1128 | 1129 | """ 1130 | 功能说明: 1131 | 1132 | 使用导航系统来使这个Entity向一个目标点移动,成功或失败会调用回调函数。 1133 | KBEngine可以有数个预先生成好的导航网格,不同的网格大小(会导致不同的导航路径)。 1134 | 任何实体,在任意时刻只能有一个移动控制器,重复调用任何移动函数将终止之前的移动控制器。 1135 | 返回一个可以用于取消这次移动的控制器ID。 1136 | 1137 | 例如: 1138 | Entity.cancel( movementID )。移动取消还可以调用Entity.cancel( "Movement" )。当移动被取消之后通知方法将不被调用。 1139 | 1140 | 回调函数如下定义: 1141 | def onMove( self, controllerId, userData ): 1142 | def onMoveFailure( self, controllerId, userData ): 1143 | 1144 | 参看: Entity.cancel 1145 | 1146 | 1147 | 1148 | 1149 | @param destination:Vector3,Entity移向的目标点 1150 | @param velocity:float,Entity的移动速度,单位m/s 1151 | @param maxMoveDistance:float,最大的移动距离 1152 | @param maxSearchDistance:float,最大的搜索距离 1153 | @param faceMovement:bool,如果实体面向移动方向则为true(默认)。如果是其它机制则为false。 1154 | @param girth:float,使用的网格大小 1155 | @param userData:object,传给通知函数的数据 1156 | @return:int,新创建的控制器ID。 1157 | """ 1158 | pass 1159 | def setAoIRadius( self, radius, hyst=5 ): 1160 | 1161 | """ 1162 | 功能说明: 1163 | 1164 | 指定Entity的感兴趣的区域大小。 1165 | 1166 | 这个函数只能用于有Witness关联的实体。 1167 | 1168 | 默认的,一个Entity的AOI区域沿着x轴和z轴延伸500米,而他的滞后区域进一步延伸5米。 1169 | 1170 | 注意:如果你设置这个大于500米,AOI半径会被锁定在500米,因为cell边界区域为500米,设置大于边界区域将不会获得到更多的信息将毫无意义。 1171 | 1172 | 你可以通过设置kbengine.xml配置选项'cellapp/defaultAoIRadius'来设置默认的AOI半径。 1173 | 1174 | 1175 | 1176 | 1177 | @param radius: float,radius指定AOI区域的半径 1178 | @param hyst:float,指定超过AOI区域的滞后区域的大小。合理的设定滞后区域将能够降低AOI碰撞的敏感度从而提高CPU执行效率。 1179 | 一个实体进入另一个实体的AOI必须跨越AOI半径区域,但实体离开AOI区域则需要移出AOI半径区域包括滞后区域。 1180 | @return: None 1181 | """ 1182 | pass 1183 | def teleport( self, nearbyMBRef, position, direction ): 1184 | 1185 | """ 1186 | 功能说明: 1187 | 1188 | 瞬间移动一个Entity到一个指定的空间。这个函数允许指定实体移动后的位置与朝向。 1189 | 如果需要在不同空间跳转( 通常用于不同场景或者房间跳转 ),可以传一个CellMailbox给这个函数( 这个mailbox所对应的实体必须在目的空间中 )。 1190 | 1191 | 这个函数只能在real的实体上被调用。 1192 | 1193 | @param nearbyMBRef:一个决定Entity跳往哪个Space的CellMailbox( 这个mailbox所对应的实体必须在目的Space中 ),它被认为是传送目的地。 1194 | 这个可以设为None,在这种情形下它会在当前的cell完成瞬移。 1195 | @param position:Entity瞬移后的坐标,是一个有3个float(x, y, z)组成的序列。 1196 | @param direction:Entity瞬移后的朝向,是一个由3个float组成的序列(roll,pitch, yaw)。 1197 | 1198 | """ 1199 | pass 1200 | def writeToDB( self ): 1201 | 1202 | """ 1203 | 功能说明: 1204 | 1205 | 这个函数保存与这个实体相关的数据到数据库,包括base实体的数据。在数据确认传到数据库之前base实体的onWriteToDB函数会被调用。 1206 | 1207 | cell实体的数据同时备份在base实体,确保遇到灾难恢复数据时数据是最新的。 1208 | 1209 | 这个函数只能在real实体且实体必须存在base部分时才允许被调用。 1210 | 1211 | 1212 | """ 1213 | pass 1214 | 1215 | 1216 | #回调函数 1217 | 1218 | def onDestroy( self ): 1219 | 1220 | """ 1221 | 如果这个函数在脚本中有实现,这个函数在调用Base.destroy()后,在实际销毁之前被调用。这个函数没有参数。 1222 | @return: 1223 | """ 1224 | pass 1225 | def onEnterTrap( self, entity, rangeXZ, rangeY, controllerID, userArg ): 1226 | 1227 | """ 1228 | 当注册了使用Entity.addProximity注册了一个范围触发器,有其他实体进入触发器时,该回调函数被调用。 1229 | @param entity:已经进入了范围的实体。 1230 | @param rangeXZ:float,给定触发器xz轴区域的大小,必须大于等于0。 1231 | @param rangeY:float,给定触发器y轴高度,必须大于等于0。 1232 | 需要注意的是,这个参数要生效必须开放kbengine_defs.xml->cellapp->coordinate_system->rangemgr_y 1233 | 开放y轴管理会带来一些消耗,因为一些游戏大量的实体都在同一y轴高度或者在差不多水平线高度,此时碰撞变得非常密集。 1234 | 3D太空类游戏或者小房间类实体较少的游戏比较适合开放此选项。 1235 | @param controllerID:这个触发器的控制器id。 1236 | @param userArg:这个参数的值由用户调用addProximity时给出,用户可以根据此参数对当前行为做一些判断。 1237 | 1238 | """ 1239 | pass 1240 | def onEnteredAoI( self, entity ): 1241 | 1242 | """ 1243 | 如果这个函数在脚本中有实现,当一个实体进入了当前实体的AOI范围,该回调被触发。 1244 | 1245 | @param entity:进入AOI范围的实体。 1246 | 1247 | 1248 | """ 1249 | pass 1250 | def onGetWitness( self ): 1251 | 1252 | """ 1253 | 如果这个函数在脚本中有实现,当实体绑定了Witness时被调用。 1254 | 也可以访问实体属性Entity.hasWitness得到实体当前的状态。 1255 | 1256 | """ 1257 | pass 1258 | def onLeaveTrap( self, entity, rangeXZ, rangeY, controllerID, userArg ): 1259 | """ 1260 | 如果这个函数在脚本中有实现,当实体离开了当前实体注册的范围触发器区域时被触发,范围触发器由Entity.addProximity注册。 1261 | 1262 | @param entity: 已经离开触发器区域的实体。 1263 | @param rangeXZ:float,给定触发器xz轴区域的大小,必须大于等于0。 1264 | @param rangeY:float,给定触发器y轴高度,必须大于等于0。 1265 | 需要注意的是,这个参数要生效必须开放kbengine_defs.xml->cellapp->coordinate_system->rangemgr_y 1266 | 开放y轴管理会带来一些消耗,因为一些游戏大量的实体都在同一y轴高度或者在差不多水平线高度,此时碰撞变得非常密集。 1267 | 3D太空类游戏或者小房间类实体较少的游戏比较适合开放此选项。 1268 | @param controllerID: 这个触发器的控制器ID。 1269 | @param userArg:这个参数的值由用户调用addProximity时给出,用户可以根据此参数对当前行为做一些判断。 1270 | 1271 | """ 1272 | pass 1273 | def onLoseWitness( self ): 1274 | 1275 | """ 1276 | 如果这个函数在脚本中有实现,当实体解除Witness时,该回调被触发。 1277 | 也可以访问实体属性Entity.hasWitness得到实体当前的状态。 1278 | 1279 | 1280 | """ 1281 | pass 1282 | def onMove( self, controllerID, userData ): 1283 | 1284 | """ 1285 | 如果这个函数在脚本中有实现,相关的Entity.moveToPoint与Entity.moveToEntity还有Entity.navigate方法被调用并且成功时会回调此函数。 1286 | 1287 | 1288 | @param controllerID:某个移动相关的控制器ID。 1289 | @param userData:这个参数值由用户在请求移动相关接口时给出。 1290 | 1291 | """ 1292 | pass 1293 | def onMoveFailure( self, controllerID, userData ): 1294 | """ 1295 | 如果这个函数在脚本中有实现,相关的Entity.moveToPoint与Entity.moveToEntity还有 1296 | Entity.navigate方法被调用并且失败时会回调此函数。 1297 | 1298 | @param controllerID:与某个移动相关的控制器ID。 1299 | @param userData:这个参数值由用户在请求移动相关接口时给出。 1300 | 1301 | """ 1302 | pass 1303 | def onRestore( self ): 1304 | 1305 | """ 1306 | 如果这个函数在脚本中有实现, 1307 | 这个函数在Cell应用程序崩溃后在其它Cell应用程序上重新创建该实体时被调用。这个函数没有参数。 1308 | 1309 | """ 1310 | pass 1311 | def onTeleport( self ): 1312 | """ 1313 | 如果这个函数在脚本中有实现,在Base.teleport调用成功之后该回调被调用。 1314 | 请注意,在cell上调用实体的teleport并不会回调此接口,如果你需要这个功能请在Entity.teleport之后调用此回调。 1315 | 1316 | 1317 | """ 1318 | pass 1319 | def onTeleportFailure( self ): 1320 | """ 1321 | 1322 | 如果这个函数在脚本中有实现,当用户调用Entity.teleport失败时该回调被调用。 1323 | """ 1324 | pass 1325 | def onTeleportSuccess( self, nearbyEntity ): 1326 | 1327 | """ 1328 | 如果这个函数在脚本中有实现,当用户调用Entity.teleport成功时该回调被调用。 1329 | @param nearbyEntity:这个参数由用户调用 Entity.teleport时给出。这是一个real实体。 1330 | 1331 | """ 1332 | pass 1333 | def onTimer( self, timerHandle, userData ): 1334 | 1335 | """ 1336 | 功能说明: 1337 | 1338 | 这个函数当一个与此实体关联的定时器触发的时候被调用。一个定时器可以使用Entity.addTimer函数添加。 1339 | @param timerHandle:定时器的id。 1340 | @param userData: 传进Entity.addTimer的integer用户数据。 1341 | 1342 | """ 1343 | pass 1344 | def onWitnessed( self, isWitnessed ): 1345 | 1346 | """ 1347 | 如果这个函数在脚本中有实现,如果当前实体进入了另一个绑定了Witness的实体的AOI范围(也可以理解为一个实体被观察者观察到了),则该实体的回调函数被调用。 1348 | 可以利用这个函数在实体被观察时激活实体的AI,实体停止被观察时可以停止AI的执行,这样可以降低服务端的计算量从而提升效率。 1349 | 1350 | @param isWitnessed:bool,实体被观察时为True,实体被停止观察时是False。 1351 | 也可以访问实体属性Entity.isWitnessed得到实体当前的状态。 1352 | 1353 | 1354 | 1355 | """ 1356 | pass 1357 | def onWriteToDB( self ): 1358 | """ 1359 | 如果这个函数在脚本中有实现,这个函数在实体将要存档到数据库时被调用。 1360 | 1361 | """ 1362 | pass 1363 | 1364 | 1365 | 1366 | 1367 | 1368 | 1369 | 1370 | 1371 | -------------------------------------------------------------------------------- /tips/CellApp/__init__.py: -------------------------------------------------------------------------------- 1 | __author__ = 'd7' 2 | --------------------------------------------------------------------------------