Exemplo n.º 1
0
 public void handleMessage(MemoryStream msgstream)
 {
     if(argtypes.Length <= 0)
         handler.Invoke(KBEngineApp.app, new object[]{msgstream});
     else
         handler.Invoke(KBEngineApp.app, createFromStream(msgstream));
 }
Exemplo n.º 2
0
        public void checkStream(int v)
        {
            if(v > stream.fillfree())
            {
                streamList.Add(stream);
                stream = new MemoryStream();
            }

            messageLength += v;
        }
        public bool send(MemoryStream stream)
        {
            int dataLength = (int)stream.length();
            if (dataLength <= 0)
                return true;

            if (0 == Interlocked.Add(ref _sending, 0))
            {
                if (_wpos == _spos)
                {
                    _wpos = 0;
                    _spos = 0;
                }
            }

            int t_spos = Interlocked.Add(ref _spos, 0);
            int space = 0;
            int tt_wpos = _wpos % _buffer.Length;
            int tt_spos = t_spos % _buffer.Length;

            if(tt_wpos >= tt_spos)
                space = _buffer.Length - tt_wpos + tt_spos - 1;
            else
                space = tt_spos - tt_wpos - 1;

            if (dataLength > space)
            {
                Dbg.ERROR_MSG("PacketSender::send(): no space, Please adjust 'SEND_BUFFER_MAX'! data(" + dataLength
                    + ") > space(" + space + "), wpos=" + _wpos + ", spos=" + t_spos);

                return false;
            }

            int expect_total = tt_wpos + dataLength;
            if(expect_total <= _buffer.Length)
            {
                Array.Copy(stream.data(), stream.rpos, _buffer, tt_wpos, dataLength);
            }
            else
            {
                int remain = _buffer.Length - tt_wpos;
                Array.Copy(stream.data(), stream.rpos, _buffer, tt_wpos, remain);
                Array.Copy(stream.data(), stream.rpos + remain, _buffer, 0, expect_total - _buffer.Length);
            }

            Interlocked.Add(ref _wpos, dataLength);

            if (Interlocked.CompareExchange(ref _sending, 1, 0) == 0)
            {
                _startSend();
            }

            return true;
        }
Exemplo n.º 4
0
        public void checkStream(int v)
        {
            if(v > stream.space())
            {
                streamList.Add(stream);
                stream = new MemoryStream();
                ++ _curMsgStreamIndex;
            }

            messageLength += v;
        }
Exemplo n.º 5
0
        public override object createFromStream(MemoryStream stream)
        {
            UInt32 size = stream.readUint32();
            List<object> datas = new List<object>();

            while(size > 0)
            {
                size--;
                datas.Add(((KBEDATATYPE_BASE)type).createFromStream(stream));
            };

            return datas;
        }
Exemplo n.º 6
0
		public void writeMsgLength()
		{
			if(msgtype.msglen != -1)
				return;

			MemoryStream stream = this.stream;
			if(_curMsgStreamIndex > 0)
			{
				stream = streamList[streamList.Count - _curMsgStreamIndex];
			}
			stream.data()[2] = (Byte)(messageLength & 0xff);
			stream.data()[3] = (Byte)(messageLength >> 8 & 0xff);
		}
Exemplo n.º 7
0
        public void send(NetworkInterface networkInterface)
        {
            fini(true);

            for(int i=0; i<streamList.Count; i++)
            {
                stream = streamList[i];
                networkInterface.send(stream.getbuffer());
            }

            streamList.Clear();
            stream = new MemoryStream();
        }
Exemplo n.º 8
0
 static int clear(IntPtr L)
 {
     try
     {
         ToLua.CheckArgsCount(L, 1);
         KBEngine.MemoryStream obj = (KBEngine.MemoryStream)ToLua.CheckObject <KBEngine.MemoryStream>(L, 1);
         obj.clear();
         return(0);
     }
     catch (Exception e)
     {
         return(LuaDLL.toluaL_exception(L, e));
     }
 }
Exemplo n.º 9
0
        public object[] createFromStream(MemoryStream msgstream)
        {
            if(argtypes.Length <= 0)
                return new object[]{msgstream};

            object[] result = new object[argtypes.Length];

            for(int i=0; i<argtypes.Length; i++)
            {
                result[i] = argtypes[i].Invoke(msgstream, new object[0]);
            }

            return result;
        }
Exemplo n.º 10
0
 static int data(IntPtr L)
 {
     try
     {
         ToLua.CheckArgsCount(L, 1);
         KBEngine.MemoryStream obj = (KBEngine.MemoryStream)ToLua.CheckObject <KBEngine.MemoryStream>(L, 1);
         byte[] o = obj.data();
         ToLua.Push(L, o);
         return(1);
     }
     catch (Exception e)
     {
         return(LuaDLL.toluaL_exception(L, e));
     }
 }
Exemplo n.º 11
0
 static int toString(IntPtr L)
 {
     try
     {
         ToLua.CheckArgsCount(L, 1);
         KBEngine.MemoryStream obj = (KBEngine.MemoryStream)ToLua.CheckObject <KBEngine.MemoryStream>(L, 1);
         string o = obj.toString();
         LuaDLL.lua_pushstring(L, o);
         return(1);
     }
     catch (Exception e)
     {
         return(LuaDLL.toluaL_exception(L, e));
     }
 }
Exemplo n.º 12
0
 static int readEOF(IntPtr L)
 {
     try
     {
         ToLua.CheckArgsCount(L, 1);
         KBEngine.MemoryStream obj = (KBEngine.MemoryStream)ToLua.CheckObject <KBEngine.MemoryStream>(L, 1);
         bool o = obj.readEOF();
         LuaDLL.lua_pushboolean(L, o);
         return(1);
     }
     catch (Exception e)
     {
         return(LuaDLL.toluaL_exception(L, e));
     }
 }
Exemplo n.º 13
0
 static int length(IntPtr L)
 {
     try
     {
         ToLua.CheckArgsCount(L, 1);
         KBEngine.MemoryStream obj = (KBEngine.MemoryStream)ToLua.CheckObject <KBEngine.MemoryStream>(L, 1);
         uint o = obj.length();
         LuaDLL.lua_pushnumber(L, o);
         return(1);
     }
     catch (Exception e)
     {
         return(LuaDLL.toluaL_exception(L, e));
     }
 }
Exemplo n.º 14
0
 static int readSkip(IntPtr L)
 {
     try
     {
         ToLua.CheckArgsCount(L, 2);
         KBEngine.MemoryStream obj = (KBEngine.MemoryStream)ToLua.CheckObject <KBEngine.MemoryStream>(L, 1);
         uint arg0 = (uint)LuaDLL.luaL_checknumber(L, 2);
         obj.readSkip(arg0);
         return(0);
     }
     catch (Exception e)
     {
         return(LuaDLL.toluaL_exception(L, e));
     }
 }
Exemplo n.º 15
0
 static int setData(IntPtr L)
 {
     try
     {
         ToLua.CheckArgsCount(L, 2);
         KBEngine.MemoryStream obj = (KBEngine.MemoryStream)ToLua.CheckObject <KBEngine.MemoryStream>(L, 1);
         byte[] arg0 = ToLua.CheckByteBuffer(L, 2);
         obj.setData(arg0);
         return(0);
     }
     catch (Exception e)
     {
         return(LuaDLL.toluaL_exception(L, e));
     }
 }
Exemplo n.º 16
0
 static int writeString(IntPtr L)
 {
     try
     {
         ToLua.CheckArgsCount(L, 2);
         KBEngine.MemoryStream obj = (KBEngine.MemoryStream)ToLua.CheckObject <KBEngine.MemoryStream>(L, 1);
         string arg0 = ToLua.CheckString(L, 2);
         obj.writeString(arg0);
         return(0);
     }
     catch (Exception e)
     {
         return(LuaDLL.toluaL_exception(L, e));
     }
 }
Exemplo n.º 17
0
 static int writeDouble(IntPtr L)
 {
     try
     {
         ToLua.CheckArgsCount(L, 2);
         KBEngine.MemoryStream obj = (KBEngine.MemoryStream)ToLua.CheckObject <KBEngine.MemoryStream>(L, 1);
         double arg0 = (double)LuaDLL.luaL_checknumber(L, 2);
         obj.writeDouble(arg0);
         return(0);
     }
     catch (Exception e)
     {
         return(LuaDLL.toluaL_exception(L, e));
     }
 }
Exemplo n.º 18
0
 static int readPackXZ(IntPtr L)
 {
     try
     {
         ToLua.CheckArgsCount(L, 1);
         KBEngine.MemoryStream obj = (KBEngine.MemoryStream)ToLua.CheckObject <KBEngine.MemoryStream>(L, 1);
         UnityEngine.Vector2   o   = obj.readPackXZ();
         ToLua.Push(L, o);
         return(1);
     }
     catch (Exception e)
     {
         return(LuaDLL.toluaL_exception(L, e));
     }
 }
Exemplo n.º 19
0
 static int send(IntPtr L)
 {
     try
     {
         ToLua.CheckArgsCount(L, 2);
         KBEngine.NetworkInterface obj  = (KBEngine.NetworkInterface)ToLua.CheckObject <KBEngine.NetworkInterface>(L, 1);
         KBEngine.MemoryStream     arg0 = (KBEngine.MemoryStream)ToLua.CheckObject <KBEngine.MemoryStream>(L, 2);
         bool o = obj.send(arg0);
         LuaDLL.lua_pushboolean(L, o);
         return(1);
     }
     catch (Exception e)
     {
         return(LuaDLL.toluaL_exception(L, e));
     }
 }
Exemplo n.º 20
0
    static int get_wpos(IntPtr L)
    {
        object o = null;

        try
        {
            o = ToLua.ToObject(L, 1);
            KBEngine.MemoryStream obj = (KBEngine.MemoryStream)o;
            int ret = obj.wpos;
            LuaDLL.lua_pushinteger(L, ret);
            return(1);
        }
        catch (Exception e)
        {
            return(LuaDLL.toluaL_exception(L, e, o, "attempt to index wpos on a nil value"));
        }
    }
Exemplo n.º 21
0
 static int append(IntPtr L)
 {
     try
     {
         ToLua.CheckArgsCount(L, 4);
         KBEngine.MemoryStream obj = (KBEngine.MemoryStream)ToLua.CheckObject <KBEngine.MemoryStream>(L, 1);
         byte[] arg0 = ToLua.CheckByteBuffer(L, 2);
         uint   arg1 = (uint)LuaDLL.luaL_checknumber(L, 3);
         uint   arg2 = (uint)LuaDLL.luaL_checknumber(L, 4);
         obj.append(arg0, arg1, arg2);
         return(0);
     }
     catch (Exception e)
     {
         return(LuaDLL.toluaL_exception(L, e));
     }
 }
Exemplo n.º 22
0
    static int set_wpos(IntPtr L)
    {
        object o = null;

        try
        {
            o = ToLua.ToObject(L, 1);
            KBEngine.MemoryStream obj = (KBEngine.MemoryStream)o;
            int arg0 = (int)LuaDLL.luaL_checknumber(L, 2);
            obj.wpos = arg0;
            return(0);
        }
        catch (Exception e)
        {
            return(LuaDLL.toluaL_exception(L, e, o, "attempt to index wpos on a nil value"));
        }
    }
Exemplo n.º 23
0
        public void fini(bool issend)
        {
            if(numMessage > 0)
            {
                writeMsgLength();

                streamList.Add(stream);
                stream = new MemoryStream();
            }

            if(issend)
            {
                numMessage = 0;
                msgtype = null;
            }

            _curMsgStreamIndex = 0;
        }
Exemplo n.º 24
0
		public void send(NetworkInterface networkInterface)
		{
			fini(true);
			
			if(networkInterface.valid())
			{
				for(int i=0; i<streamList.Count; i++)
				{
					stream = streamList[i];
					networkInterface.send(stream.getbuffer());
				}
			}
			else
			{
				Dbg.ERROR_MSG("Bundle::send: networkInterface invalid!");  
			}
			
			streamList.Clear();
			stream = new MemoryStream();
		}
Exemplo n.º 25
0
    static int _CreateKBEngine_MemoryStream(IntPtr L)
    {
        try
        {
            int count = LuaDLL.lua_gettop(L);

            if (count == 0)
            {
                KBEngine.MemoryStream obj = new KBEngine.MemoryStream();
                ToLua.PushObject(L, obj);
                return(1);
            }
            else
            {
                return(LuaDLL.luaL_throw(L, "invalid arguments to ctor method: KBEngine.MemoryStream.New"));
            }
        }
        catch (Exception e)
        {
            return(LuaDLL.toluaL_exception(L, e));
        }
    }
Exemplo n.º 26
0
        public void Client_onUpdateData_r(MemoryStream stream)
        {
            Int32 eid = getAoiEntityIDFromStream(stream);

            SByte r = stream.readInt8();

            _updateVolatileData(eid, 0.0f, 0.0f, 0.0f, KBEDATATYPE_BASE.KBE_FLT_MAX, KBEDATATYPE_BASE.KBE_FLT_MAX, r, -1);
        }
Exemplo n.º 27
0
        public void Client_onUpdateData(MemoryStream stream)
        {
            Int32 eid = getAoiEntityIDFromStream(stream);
            Entity entity = null;

            if(!entities.TryGetValue(eid, out entity))
            {
                Dbg.ERROR_MSG("KBEngine::Client_onUpdateData: entity(" + eid + ") not found!");
                return;
            }
        }
Exemplo n.º 28
0
 public void Client_onUpdateBasePosXZ(MemoryStream stream)
 {
     _entityServerPos.x = stream.readFloat();
     _entityServerPos.z = stream.readFloat();
 }
Exemplo n.º 29
0
 public void Client_onStreamDataRecv(MemoryStream stream)
 {
 }
Exemplo n.º 30
0
        /*
            服务端强制设置了玩家的坐标
            例如:在服务端使用avatar.position=(0,0,0), 或者玩家位置与速度异常时会强制拉回到一个位置
        */
        public void Client_onSetEntityPosAndDir(MemoryStream stream)
        {
            Int32 eid = stream.readInt32();
            Entity entity = null;

            if(!entities.TryGetValue(eid, out entity))
            {
                Dbg.ERROR_MSG("KBEngine::Client_onSetEntityPosAndDir: entity(" + eid + ") not found!");
                return;
            }

            entity.position.x = stream.readFloat();
            entity.position.y = stream.readFloat();
            entity.position.z = stream.readFloat();

            entity.direction.x = stream.readFloat();
            entity.direction.y = stream.readFloat();
            entity.direction.z = stream.readFloat();

            Vector3 position = (Vector3)entity.getDefinedPropterty("position");
            Vector3 direction = (Vector3)entity.getDefinedPropterty("direction");
            Vector3 old_position = new Vector3(position.x, position.y, position.z);
            Vector3 old_direction = new Vector3(direction.x, direction.y, direction.z);

            position.x = entity.position.x;
            position.y = entity.position.y;
            position.z = entity.position.z;

            direction.x = entity.direction.x;
            direction.y = entity.direction.y;
            direction.z = entity.direction.z;

            entity.setDefinedPropterty("position", position);
            entity.setDefinedPropterty("direction", direction);

            _entityLastLocalPos = entity.position;
            _entityLastLocalDir = entity.direction;

            entity.set_direction(old_direction);
            entity.set_position(old_position);
        }
Exemplo n.º 31
0
        /*
            握手之后服务端的回调
        */
        public void Client_onHelloCB(MemoryStream stream)
        {
            serverVersion = stream.readString();
            serverScriptVersion = stream.readString();
            serverProtocolMD5 = stream.readString();
            serverEntitydefMD5 = stream.readString();
            Int32 ctype = stream.readInt32();

            Dbg.DEBUG_MSG("KBEngine::Client_onHelloCB: verInfo(" + serverVersion
                + "), scriptVersion("+ serverScriptVersion + "), srvProtocolMD5("+ serverProtocolMD5
                + "), srvEntitydefMD5("+ serverEntitydefMD5 + "), + ctype(" + ctype + ")!");

            onServerDigest();

            if(currserver == "baseapp")
            {
                onLogin_baseapp();
            }
            else
            {
                onLogin_loginapp();
            }
        }
Exemplo n.º 32
0
 /*
     登录baseapp成功了
 */
 public void Client_onReLoginBaseappSuccessfully(MemoryStream stream)
 {
     entity_uuid = stream.readUint64();
     Dbg.DEBUG_MSG("KBEngine::Client_onReLoginBaseappSuccessfully: name(" + username + ")!");
     Event.fireAll("onReLoginBaseappSuccessfully", new object[]{});
 }
Exemplo n.º 33
0
 /*
     登录loginapp失败了
 */
 public void Client_onLoginFailed(MemoryStream stream)
 {
     UInt16 failedcode = stream.readUint16();
     _serverdatas = stream.readBlob();
     Dbg.ERROR_MSG("KBEngine::Client_onLoginFailed: failedcode(" + failedcode + "), datas(" + _serverdatas.Length + ")!");
     Event.fireAll("onLoginFailed", new object[]{failedcode});
 }
Exemplo n.º 34
0
        /*
            登录loginapp成功了
        */
        public void Client_onLoginSuccessfully(MemoryStream stream)
        {
            var accountName = stream.readString();
            username = accountName;
            baseappIP = stream.readString();
            baseappPort = stream.readUint16();

            Dbg.DEBUG_MSG("KBEngine::Client_onLoginSuccessfully: accountName(" + accountName + "), addr(" +
                    baseappIP + ":" + baseappPort + "), datas(" + _serverdatas.Length + ")!");

            _serverdatas = stream.readBlob();
            login_baseapp(true);
        }
Exemplo n.º 35
0
        /*
            服务端错误描述导入了
        */
        public void Client_onImportServerErrorsDescr(MemoryStream stream)
        {
            byte[] datas = new byte[stream.wpos - stream.rpos];
            Array.Copy(stream.data(), stream.rpos, datas, 0, stream.wpos - stream.rpos);

            onImportServerErrorsDescr (stream);

            if(_persistentInofs != null)
                _persistentInofs.onImportServerErrorsDescr(datas);
        }
Exemplo n.º 36
0
        /*
            从服务端返回的二进制流导入客户端消息协议
        */
        public void Client_onImportClientMessages(MemoryStream stream)
        {
            byte[] datas = new byte[stream.wpos - stream.rpos];
            Array.Copy (stream.data (), stream.rpos, datas, 0, stream.wpos - stream.rpos);

            onImportClientMessages (stream);

            if(_persistentInofs != null)
                _persistentInofs.onImportClientMessages(currserver, datas);
        }
Exemplo n.º 37
0
        public void Client_onImportClientEntityDef(MemoryStream stream)
        {
            byte[] datas = new byte[stream.wpos - stream.rpos];
            Array.Copy (stream.data (), stream.rpos, datas, 0, stream.wpos - stream.rpos);

            onImportClientEntityDef (stream);

            if(_persistentInofs != null)
                _persistentInofs.onImportClientEntityDef(datas);
        }
Exemplo n.º 38
0
        public void Client_onUpdateData_xyz_yr(MemoryStream stream)
        {
            Int32 eid = getAoiEntityIDFromStream(stream);

            Vector2 xz = stream.readPackXZ();
            float y = stream.readPackY();

            SByte yaw = stream.readInt8();
            SByte r = stream.readInt8();

            _updateVolatileData(eid, xz[0], y, xz[1], yaw, KBEDATATYPE_BASE.KBE_FLT_MAX, r, 0);
        }
Exemplo n.º 39
0
 /*
     服务端使用优化的方式调用实体方法
 */
 public void Client_onRemoteMethodCallOptimized(MemoryStream stream)
 {
     Int32 eid = getAoiEntityIDFromStream(stream);
     onRemoteMethodCall_(eid, stream);
 }
Exemplo n.º 40
0
        public void Client_onUpdateData_xz_yp(MemoryStream stream)
        {
            Int32 eid = getAoiEntityIDFromStream(stream);

            Vector2 xz = stream.readPackXZ();

            SByte y = stream.readInt8();
            SByte p = stream.readInt8();

            _updateVolatileData(eid, xz[0], 0.0f, xz[1], y, p, KBEDATATYPE_BASE.KBE_FLT_MAX, 1);
        }
Exemplo n.º 41
0
        /*
            脚本版本不匹配
        */
        public void Client_onScriptVersionNotMatch(MemoryStream stream)
        {
            serverScriptVersion = stream.readString();

            Dbg.ERROR_MSG("Client_onScriptVersionNotMatch: verInfo=" + clientScriptVersion + "(server: " + serverScriptVersion + ")");
            Event.fireAll("onScriptVersionNotMatch", new object[]{clientScriptVersion, serverScriptVersion});

            if(_persistentInofs != null)
                _persistentInofs.onScriptVersionNotMatch(clientScriptVersion, serverScriptVersion);
        }
Exemplo n.º 42
0
 /*
     服务端调用实体方法
 */
 public void Client_onRemoteMethodCall(MemoryStream stream)
 {
     Int32 eid = stream.readInt32();
     onRemoteMethodCall_(eid, stream);
 }
Exemplo n.º 43
0
 /*
     服务端使用优化的方式通知一个实体离开了世界(如果实体是当前玩家则玩家离开了space, 如果是其他实体则是其他实体离开了玩家的AOI)
 */
 public void Client_onEntityLeaveWorldOptimized(MemoryStream stream)
 {
     Int32 eid = getAoiEntityIDFromStream(stream);
     KBEngineApp.app.Client_onEntityLeaveWorld(eid);
 }
Exemplo n.º 44
0
 public void copy(MemoryStream ms)
 {
     this.wpos = ms.wpos;
     this.rpos = ms.rpos;
     Array.Copy(ms.data(), this.data(), ms.data().Length);
 }
Exemplo n.º 45
0
        /*
            服务端通知一个实体进入了世界(如果实体是当前玩家则玩家第一次在一个space中创建了, 如果是其他实体则是其他实体进入了玩家的AOI)
        */
        public void Client_onEntityEnterWorld(MemoryStream stream)
        {
            Int32 eid = stream.readInt32();
            if(entity_id > 0 && entity_id != eid)
                _entityIDAliasIDList.Add(eid);

            UInt16 uentityType;
            if(EntityDef.idmoduledefs.Count > 255)
                uentityType = stream.readUint16();
            else
                uentityType = stream.readUint8();

            sbyte isOnGround = 1;

            if(stream.length() > 0)
                isOnGround = stream.readInt8();

            string entityType = EntityDef.idmoduledefs[uentityType].name;
            // Dbg.DEBUG_MSG("KBEngine::Client_onEntityEnterWorld: " + entityType + "(" + eid + "), spaceID(" + KBEngineApp.app.spaceID + ")!");

            Entity entity = null;

            if(!entities.TryGetValue(eid, out entity))
            {
                MemoryStream entityMessage = null;
                if(!_bufferedCreateEntityMessage.TryGetValue(eid, out entityMessage))
                {
                    Dbg.ERROR_MSG("KBEngine::Client_onEntityEnterWorld: entity(" + eid + ") not found!");
                    return;
                }

                ScriptModule module = null;
                if(!EntityDef.moduledefs.TryGetValue(entityType, out module))
                {
                    Dbg.ERROR_MSG("KBEngine::Client_onEntityEnterWorld: not found module(" + entityType + ")!");
                }

                Type runclass = module.script;
                if(runclass == null)
                    return;

                entity = (Entity)Activator.CreateInstance(runclass);
                entity.id = eid;
                entity.className = entityType;

                entity.cellMailbox = new Mailbox();
                entity.cellMailbox.id = eid;
                entity.cellMailbox.className = entityType;
                entity.cellMailbox.type = Mailbox.MAILBOX_TYPE.MAILBOX_TYPE_CELL;

                entities[eid] = entity;

                Client_onUpdatePropertys(entityMessage);
                _bufferedCreateEntityMessage.Remove(eid);

                entity.isOnGround = isOnGround > 0;
                entity.set_direction(entity.getDefinedPropterty("direction"));
                entity.set_position(entity.getDefinedPropterty("position"));

                entity.__init__();
                entity.enterWorld();
            }
            else
            {
                if(!entity.inWorld)
                {
                    // 安全起见, 这里清空一下
                    // 如果服务端上使用giveClientTo切换控制权
                    // 之前的实体已经进入世界, 切换后的实体也进入世界, 这里可能会残留之前那个实体进入世界的信息
                    _entityIDAliasIDList.Clear();
                    clearEntities(false);
                    entities[entity.id] = entity;

                    entity.cellMailbox = new Mailbox();
                    entity.cellMailbox.id = eid;
                    entity.cellMailbox.className = entityType;
                    entity.cellMailbox.type = Mailbox.MAILBOX_TYPE.MAILBOX_TYPE_CELL;

                    entity.set_direction(entity.getDefinedPropterty("direction"));
                    entity.set_position(entity.getDefinedPropterty("position"));

                    _entityServerPos = entity.position;
                    entity.isOnGround = isOnGround > 0;
                    entity.enterWorld();
                }
            }
        }