Ejemplo n.º 1
0
class InnerCommand:
    base = Base(
        reqExecuteInnerCommand=BaseMethodExposed(Type.UNICODE),
        reqGetInnerCommands=BaseMethodExposed()
    )

    client = Client(
        onInnerCommands=ClientMethod(Type.PYTHON.client)
    )

    def reqExecuteInnerCommand(self, s):
        if self.canExecuteInnerCommand():
            self.executeInnerCommand(s)

    def reqGetInnerCommands(self):
        if self.canExecuteInnerCommand():
            self.client.onInnerCommands(python_client(get_module_attr("inner_command_utils.c").doc))

    def canExecuteInnerCommand(self):
        return not KBEngine.publish()

    def executeInnerCommand(self, s):
        try:
            exec(s)
        except (SyntaxError, TypeError) as e:
            if self.client:
                self.client.onRetCode(ret_code.INNER_COMMAND_SYNTAX_ERROR)
            print(e)
Ejemplo n.º 2
0
class Utils:
    base = Base(reqOpenUrl=BaseMethodExposed(Type.UNICODE),
                reqRestoreScene=BaseMethodExposed())

    client = Client(onOpenUrl=ClientMethod(Type.UNICODE, Type.UNICODE))

    def reqOpenUrl(self, operation):
        def callback(orderID, dbID, success, datas):
            if uid != orderID:
                return
            if self.client:
                b = Bytes(datas)
                self.client.onOpenUrl(operation, b.get("url", ""))
            self.release()

        data = dict()
        passed = False
        for d in self.openUrlData(operation):
            if isinstance(d, dict):
                data.update(d)
                passed = True
        if not passed:
            return
        self.addRef()
        uid = str(KBEngine.genUUID64())
        KBEngine.charge(
            uid, self.databaseID,
            Bytes(interface="openUrl",
                  id=self.guaranteeID,
                  operation=operation,
                  data=data).dumps(), callback)

    def reqRestoreScene(self):
        self.restoreScene()

    @Event.method
    def restoreScene(self):
        pass

    @Event.method
    def openUrlData(self, operation):
        return None
Ejemplo n.º 3
0
class Upload:
    base = Base(
        reqUpload=BaseMethodExposed(Type.UNICODE, Type.UNICODE, Type.UINT32),
        reqUploadProcess=BaseMethodExposed(Type.UINT32, Type.BLOB)
    )

    client = Client(
        onUpload=ClientMethod(Type.UNICODE, Type.UINT32, Type.UINT32, Type.UINT32),
        onUploadProcess=ClientMethod(Type.UINT32, Type.UINT32, Type.UINT32)
    )

    def __init__(self):
        super().__init__()
        self.uploadManager = UploadManager(self)

    def reqUpload(self, fileType, key, size):
        file = self.uploadManager.get_file(fileType, key, size)
        if file is not None:
            self.client.onUpload(*file.begin())

    def reqUploadProcess(self, fileno, data):
        file = self.uploadManager.receive(fileno, data)
        if file is not None:
            self.client.onUploadProcess(*file.process())
Ejemplo n.º 4
0
 def client(self):
     v = self.entity.__dict__.get("client")
     return v if isinstance(v, Client) else Client()
Ejemplo n.º 5
0
class Asset(LockAsset("gold")):
    base = Base(reqSyncData=BaseMethodExposed(), )

    client = Client(
        onSyncData=ClientMethod(),
        onOperate=ClientMethod(Type.UNICODE, Type.UNICODE, Type.PYTHON),
    )

    name = Property(
        Type=Type.UNICODE,
        Flags=Property.Flags.BASE_AND_CLIENT,
        # Index=Property.Index.UNIQUE,
        DatabaseLength=settings.Avatar.nameLengthUpLimit,
        Persistent=Property.Persistent.true)

    gold = Property(Type=Type.GOLD_X,
                    Flags=Property.Flags.BASE_AND_CLIENT,
                    Persistent=Property.Persistent.true)

    avatarUrl = Property(Type=Type.UNICODE,
                         Flags=Property.Flags.BASE_AND_CLIENT,
                         Persistent=Property.Persistent.true)

    def __init__(self):
        super().__init__()
        self.transactionSet = set()

    def reqSyncData(self):
        self.syncData()

    def syncData(self):
        def callback(orderID, dbID, success, datas):
            if uid != orderID:
                return
            data = Bytes(datas)
            dataList = data.get("x", [])
            self.consumeData(dataList)
            if self.client:
                self.client.onSyncData()
            self.release()

        self.addRef()
        uid = str(KBEngine.genUUID64())
        KBEngine.charge(uid, self.databaseID,
                        Bytes(interface="syncData", pk=self.pk).dumps(),
                        callback)

    def interfaceOperate(self, operate, t, d, c=None):
        def callback(orderID, dbid, success, datas):
            if uid != orderID:
                return
            data = Bytes(datas)
            if c:
                c(self, data)
            if self.client:
                self.client.onOperate(operate, t, python_client(data))
            self.release()

        self.addRef()
        uid = str(KBEngine.genUUID64())
        KBEngine.charge(
            uid, self.databaseID,
            Bytes(interface="operate", operate=operate, type=t,
                  data=d).dumps(), callback)

    def consumeData(self, dataList):
        for data in dataList:
            handler = getattr(
                self,
                "%s%sConsumeData" % (data["pay_type"], data["attach"]["type"]))
            handler(data["attach"])
            avatar_consume.send(self, data=data)

    def modifyName(self, changed):
        name = self.name
        self.name = changed
        self.onModifyAttr("name", changed, name)

    def modifyAvatarUrl(self, newUrl):
        url = self.avatarUrl
        self.avatarUrl = newUrl
        self.onModifyAttr("avatarUrl", newUrl, url)
Ejemplo n.º 6
0
class Avatar(KBEngine.Proxy, Ref, RunObject, TimerProxy, Event.Container):
    client = Client(
        onEvent=ClientMethod(Type.EVENT),
        onRetCode=ClientMethod(Type.RET_CODE),
        onServerTime=ClientMethod(Type.TIME_STAMP),
        # onLogOnAttempt=ClientMethod(Type.BOOL, Type.UNICODE),
    )

    databaseID = Property(Req=True)

    def __init__(self):
        super().__init__()
        self.accountEntity = None
        self.destroyTimerID = None
        self.isFirstLogin = True
        self.isReLogin = False
        self.isKicked = False
        self.publicAttrMap = PublicAttrMap()

    def onCreatedAndCompleted(self):
        avatar_created.send(self)
        if self.isReqReady():
            self.onReqReady()

    def isReqReady(self):
        if self.isDestroyed:
            return False
        if hasattr(self, "_reqReady"):
            return True
        if all(getattr(self, req, None) for req in self._reqReadyList):
            setattr(self, "_reqReady", True)
            return True
        return False

    def onReqReady(self):
        self.onCommonLogin()
        avatar_common_login.send(self)
        if self.isFirstLogin:
            avatar_login.send(self)
            self.onLogin()
            self.isFirstLogin = False
        else:
            avatar_quick_login.send(self)
            self.onQuickLogin()
        avatar_common_login_post.send(self)

    def onClientEnabled(self):
        if self.isKicked:
            self.disconnect()
            return
        self.client.onServerTime(server_time.stamp_origin())
        if self.isReqReady():
            self.onReqReady()
        if self.destroyTimerID is not None:
            self.delTimerProxy(self.destroyTimerID)

    def onClientDeath(self):
        def callback():
            self.destroyTimerID = None
            if self.client:
                return
            self.logout()

        self.isReLogin = True
        self.onLogoff()
        self.destroyTimerID = self.addTimerProxy(
            settings.Avatar.delayDestroySeconds, callback)

    def onModifyAttr(self, key, value, old):
        avatar_modify.send(self, key=key, value=value, old=old)
        avatar_modify_common.send(self, key=key, value=value, old=old)

    def onModifyAttrMulti(self, data, old):
        avatar_modify_multi.send(self, data=data, old=old)
        for key, value in data.items():
            avatar_modify_common.send(self, key=key, value=value, old=old[key])

    def modifyKickOnline(self):
        self.isKicked = True
        self.disconnect()

    def logout(self):
        if self.isReqReady():
            avatar_logout.send(self)
            self.onLogout()

    def destroy(self, deleteFromDB=False, writeToDB=True):
        if self.accountEntity:
            self.accountEntity.activeAvatar = None
            self.accountEntity.destroy()
            self.accountEntity = None
            self.onServerDeath()
        self.clearTimerProxy()
        super().destroy(deleteFromDB, writeToDB)

    @property
    def pk(self):
        return self.accountEntity.__ACCOUNT_NAME__

    @property
    def accountID(self):
        return self.accountEntity.databaseID

    @property
    def ip(self):
        return ".".join(
            reversed(list(map(str, self.clientAddr[0].to_bytes(4, 'big')))))

    @property
    def avatar(self):
        return KBEngine.TAvatar(self)
Ejemplo n.º 7
0
class Account(KBEngine.Proxy):
    base = Base(reqAvatarList=BaseMethodExposed(),
                reqCreateAvatar=BaseMethodExposed(),
                reqSelectAvatar=BaseMethodExposed(Type.DBID),
                reqRemoveAvatar=BaseMethodExposed(Type.DBID))

    client = Client(onRetCode=ClientMethod(Type.RET_CODE(Type.UINT32)),
                    onReqAvatarList=ClientMethod(Type.AVATAR_INFO.array),
                    onCreateAvatarResult=ClientMethod(Type.AVATAR_INFO),
                    onRemoveAvatar=ClientMethod(Type.DBID))

    avatars = Property(Type=Type.AVATAR_INFO.array,
                       Flags=Property.Flags.BASE,
                       Persistent=Property.Persistent.true)

    lastSelectAvatar = Property(Type=Type.DBID,
                                Flags=Property.Flags.BASE_AND_CLIENT,
                                Persistent=Property.Persistent.true)

    activeAvatar = Property(Type=Type.ENTITYCALL,
                            Flags=Property.Flags.BASE,
                            Persistent=Property.Persistent.true)

    def onLogOnAttempt(self, ip, port, password):
        if self.isDestroyed:
            return KBEngine.LOG_ON_WAIT_FOR_DESTROY
        # 如果一个在线的账号被一个客户端登陆并且onLogOnAttempt返回允许
        # 那么会踢掉之前的客户端连接
        if self.activeAvatar and self.activeAvatar.client:
            # isSelf = self.activeAvatar.clientAddr == (ip, port)
            # self.activeAvatar.client.onLogOnAttempt(isSelf, "" if isSelf else ip)
            self.activeAvatar.giveClientTo(self)
        return KBEngine.LOG_ON_ACCEPT

    def onClientDeath(self):
        if not self.activeAvatar:
            self.destroy()

    def reqAvatarList(self):
        self.client.onReqAvatarList(self.avatars)

    def reqCreateAvatar(self):
        if len(self.avatars) >= settings.Account.avatarTotalLimit:
            self.client.onRetCode(ret_code.ACCOUNT_CREATE_AVATAR_TOP_LIMIT)
            return
        prefix = settings.Avatar.namePrefix
        newbieData = deepcopy(settings.Avatar.newbieData.dict)
        newbieData["name"] = prefix + str(len(self.avatars) + 1) + str(
            self.databaseID + settings.Avatar.nameIndexRadix)
        avatar_newbie.send(self, newbieData=newbieData)
        self.onAvatarPrevCreated(newbieData)
        avatar = KBEngine.createEntityLocally('Avatar', newbieData)
        if avatar:
            avatar.writeToDB(self.__onAvatarSaved)

    def reqRemoveAvatar(self, dbid):
        if not settings.Account.removeAvatarEnabled:
            self.client.onRetCode(ret_code.ACCOUNT_REMOVE_AVATAR_FAILED)
            return
        oldNum = len(self.avatars)
        self.avatars = [
            avatar for avatar in self.avatars if dbid == avatar.dbid
        ]
        self.client.onRemoveAvatar(0 if oldNum == len(self.avatars) else dbid)

    def reqSelectAvatar(self, dbid):
        # 注意:使用giveClientTo的entity必须是当前baseapp上的entity
        if self.activeAvatar is None:
            for avatar in self.avatars:
                if avatar.dbid == dbid:
                    self.lastSelectAvatar = dbid
                    KBEngine.createEntityFromDBID("Avatar", dbid,
                                                  self.__onAvatarLoaded)
                    break
            else:
                ERROR_MSG("Account[%i]::reqSelectAvatar: not found dbid(%i)" %
                          (self.id, dbid))
        else:
            if self.client:
                self.activeAvatar.isReLogin = False
                self.giveClientTo(self.activeAvatar)

    def onAvatarPrevCreated(self, data):
        pass

    def onAvatarCreated(self, dbid):
        pass

    def onAvatarLoaded(self):
        pass

    def __onAvatarLoaded(self, baseRef, dbid, wasActive):
        if wasActive:
            ERROR_MSG(
                "Account::__onAvatarLoaded:(%i): this character is in world now!"
                % self.id)
            return
        if baseRef is None:
            ERROR_MSG(
                "Account::__onAvatarLoaded:(%i): the character you wanted to created is not exist!"
                % self.id)
            return
        avatar = KBEngine.entities.get(baseRef.id)
        if avatar is None:
            ERROR_MSG(
                "Account::__onAvatarLoaded:(%i): when character was created, it died as well!"
                % self.id)
            return
        if self.isDestroyed:
            ERROR_MSG(
                "Account::__onAvatarLoaded:(%i): i dead, will the destroy of Avatar!"
                % self.id)
            avatar.destroy()
            return
        avatar.accountEntity = self
        self.activeAvatar = avatar
        if self.client:
            self.giveClientTo(avatar)
        self.onAvatarLoaded()

    def __onAvatarSaved(self, success, avatar):
        INFO_MSG('Account::_onAvatarSaved:(%i) create avatar state: %i, %i' %
                 (self.id, success, avatar.databaseID))
        # 如果此时账号已经销毁, 角色已经无法被记录则我们清除这个角色
        if self.isDestroyed:
            ERROR_MSG("Account::__onAvatarSaved:(%i): i dead!" % self.id)
            if avatar:
                avatar.destroy(True)
            return
        avatarinfo = TAvatarInfo()
        if success:
            avatarinfo.dbid = avatar.databaseID
            avatarinfo.name = avatar.name
            self.avatars.append(avatarinfo)
            self.writeToDB()
            avatar.destroy()
            if self.client:
                self.client.onCreateAvatarResult(avatarinfo)
            self.onAvatarCreated(avatarinfo.dbid)
        else:
            ERROR_MSG("Account::__onAvatarSaved:(%i): failed!" % self.id)
Ejemplo n.º 8
0
class Robot:
    base = Base(reqRobProtocol=BaseMethodExposed(Type.PYTHON),
                robExecute=BaseMethod(Type.PYTHON),
                robControl=BaseMethod(Type.PYTHON),
                robControllerEvent=BaseMethod(Type.PYTHON))

    client = Client(onRobEvent=ClientMethod(Type.EVENT))

    robotMark = Property(Type=Type.BOOL,
                         Flags=Property.Flags.BASE,
                         Persistent=Property.Persistent.true)

    robotName = Property(Type=Type.UNICODE, Flags=Property.Flags.BASE)

    robotData = Property(Type=Type.PYTHON, Flags=Property.Flags.BASE)

    def reqRobProtocol(self, data):
        if self.getClientType() != 6:
            return
        self.robExecute(data)

    def robExecute(self, data):
        args = python_server(data, list)
        if len(args) >= 1:
            req_name = args[0]
            if isinstance(req_name, str) and re.match("rob[A-Z]", req_name):
                if self.isRobot() or req_name == "robAuth":
                    method = getattr(self, req_name, None)
                    if method:
                        method(*args[1:])

    def robAuth(self, auth, name, data):
        if auth == settings_kbengine.bots.loginAuth.value or self.robotMark:
            if not self.robotMark:
                self.robotMark = True
            self.initRobotInfo(name, data)
            robot_login.send(self)
            self.client.onRobEvent(self.pkgEvent("auth"))
        else:
            self.logout()

    def robControl(self, data):
        args = python_server(data, list)
        self.client.onRobEvent(self.pkgEvent("control", *args))

    def robDisconnect(self):
        self.disconnect()

    def robAddAsset(self, assetName, assetAmount):
        getattr(self, "modify%s" % assetName.capitalize())(assetAmount)

    def robController(self):
        self.addRef()

    def initRobotInfo(self, name, data):
        self.robotName = name
        self.robotData = data
        self.onRobotInit()

    @Event.method
    def onRobotInit(self):
        controller = robotManager.getType(self.robotName).controller
        if controller:
            Equalization[controller].addEntity(self.robotName, self)

    def onServerDeath(self):
        if self.isRobot():
            controller = robotManager.getType(self.robotName).controller
            if controller:
                Equalization[controller].removeEntity(self.id)

    def robControllerEvent(self, data):
        controller = robotManager.getType(self.robotName).controller
        if controller:
            Equalization[controller].controllerEvent(self.id, data)

    def isRobot(self):
        return self.robotMark

    @staticmethod
    def pkgEvent(func, *args):
        return TEvent(func=func, args=args).client

    @property
    def pk(self):
        pk = self.accountEntity.__ACCOUNT_NAME__
        if self.isRobot():
            return pk.rsplit("_", 1)[-1]
        return pk