예제 #1
0
        public static ValueTask SendReactorRpcAsync(this IInnerNetObject innerNetObject, IClient target, IReactorCustomRpc customRpc, IMessageWriter data, int?targetClientId = null)
        {
            var clientInfo = target.GetReactor();

            if (clientInfo == null)
            {
                throw new ArgumentException("Tried to send reactor rpc to vanilla client");
            }

            var targetMod = clientInfo.Mods.Single(x => x.Id == customRpc.ModId);

            using var writer = innerNetObject.Game.StartRpc(innerNetObject.NetId, (RpcCalls) 255, targetClientId);

            writer.WritePacked(targetMod.NetId);
            writer.WritePacked(customRpc.Id);

            writer.StartMessage(0);
            writer.Write(data.ToByteArray(false));
            writer.EndMessage();

            writer.EndMessage();
            writer.EndMessage();

            return(target.Connection !.SendAsync(writer));
        }
        public async ValueTask <bool> HandleRpcAsync(IInnerNetObject innerNetObject, IClientPlayer sender, IClientPlayer?target, IMessageReader reader)
        {
            var clientInfo = sender.Client.GetReactor();

            if (clientInfo == null)
            {
                await sender.Client.ReportCheatAsync(new CheatContext(nameof(Rpc255Reactor)), "Client tried to send reactor custom rpc without completing handshake");

                return(false);
            }

            Deserialize(reader, out var modNetId, out var rpcId);

            var mod = clientInfo.Mods.Single(x => x.NetId == modNetId);

            _logger.LogTrace("Received custom rpc: {rpcId} from mod {mod}", rpcId, mod.Id);

            var relay         = true;
            var messageReader = reader.ReadMessage();

            var customRpc = _manager.Rpcs.SingleOrDefault(x => x.ModId == mod.Id && x.Id == rpcId);

            if (customRpc != null)
            {
                if (!await customRpc.HandleAsync(innerNetObject, sender, target, messageReader.Copy()))
                {
                    relay = false;
                }
            }

            customRpc ??= new DummyReactorCustomRpc(mod.Id, rpcId);

            if (relay)
            {
                var game = innerNetObject.Game;

                var data = _writerProvider.Get();
                Buffer.BlockCopy(messageReader.Buffer, messageReader.Offset, data.Buffer, data.Position, messageReader.Length);
                data.Position += messageReader.Length;
                if (data.Position > data.Length)
                {
                    data.Length = data.Position;
                }

                if (target != null)
                {
                    await innerNetObject.SendReactorRpcAsync(target.Client, customRpc, data, target.Client.Id);
                }
                else
                {
                    foreach (var targetPlayer in game.Players.Where(x => x != sender))
                    {
                        await innerNetObject.SendReactorRpcAsync(targetPlayer.Client, customRpc, data);
                    }
                }
            }

            return(false);
        }
예제 #3
0
 public void Write(IInnerNetObject innerNetObject)
 {
     if (innerNetObject == null)
     {
         this.Write(0);
     }
     else
     {
         this.WritePacked(innerNetObject.NetId);
     }
 }
 public ValueTask <bool> HandleAsync(IInnerNetObject innerNetObject, IClientPlayer sender, IClientPlayer?target, IMessageReader reader)
 {
     return(HandleAsync((T)innerNetObject, sender, target, reader));
 }
 public ValueTask <bool> HandleAsync(IInnerNetObject innerNetObject, IClientPlayer sender, IClientPlayer?target, IMessageReader reader)
 {
     throw new NotSupportedException();
 }
예제 #6
0
 /// <inheritdoc />
 public bool IsOwner(IInnerNetObject netObject)
 {
     return(Client.Id == netObject.OwnerId);
 }