示例#1
0
 public static Player FindPlayer(this UchuServer @this, IRakConnection connection)
 {
     if (connection == null)
     {
         return(null);
     }
     return(((WorldUchuServer)@this).Zones.SelectMany(z => z.Players).FirstOrDefault(
                player => player.Connection.EndPoint.Equals(connection.EndPoint)
                ));
 }
示例#2
0
        public async Task ValidateClient(SessionInfoPacket packet, IRakConnection connection)
        {
            if (packet == null)
            {
                throw new ArgumentNullException(nameof(packet),
                                                ResourceStrings.ClientHandler_ValidateClient_PacketNullException);
            }

            await UchuServer.ValidateUserAsync(connection, packet.Username, packet.SessionKey)
            .ConfigureAwait(false);
        }
示例#3
0
        public async Task ValidateClientHandler(SessionInfoPacket packet, IRakConnection connection)
        {
            Logger.Information($"{connection.EndPoint}'s validating client for world!");

            var verified = await UchuServer.ValidateUserAsync(connection, packet.Username, packet.SessionKey);

            if (!verified)
            {
                return;
            }

            var session = UchuServer.SessionCache.GetSession(connection.EndPoint);

            await using var ctx = new UchuContext();

            // Try to find the player, disconnect if the player is invalid
            var character = await ctx.Characters.FindAsync(session.CharacterId);

            if (character == null)
            {
                Logger.Warning(
                    $"{connection} attempted to connect to world with an invalid character {session.CharacterId}"
                    );

                connection.Send(new DisconnectNotifyPacket
                {
                    DisconnectId = DisconnectId.CharacterNotFound
                });

                return;
            }

            // Initialize zone for player
            var zoneId = (ZoneId)character.LastZone;

            if (zoneId == 0)
            {
                zoneId = 1000;
            }

            var worldServer = (WorldUchuServer)UchuServer;
            var zone        = await worldServer.GetZoneAsync(zoneId);

            UchuServer.SessionCache.SetZone(connection.EndPoint, zoneId);

            connection.Send(new WorldInfoPacket
            {
                ZoneId        = zoneId,
                Checksum      = zone.Checksum,
                SpawnPosition = zone.SpawnPosition
            });
        }
示例#4
0
        private static async Task Main(string[] args)
        {
            if (args.Length != 2)
            {
                throw new ArgumentException("Expected 2 argument.");
            }

            if (!Guid.TryParse(args[0], out var id))
            {
                throw new ArgumentException($"{args[0]} is not a valid GUID");
            }

            Id = id;

            await ConfigureAsync(args[1]).ConfigureAwait(false);

            Logger.Debug($"Process ID: {Process.GetCurrentProcess().Id}");

            try
            {
                switch (ServerType)
                {
                case ServerType.Authentication:
                    await UchuServer.StartAsync(typeof(LoginHandler).Assembly, true);

                    break;

                case ServerType.Character:
                    await UchuServer.StartAsync(typeof(CharacterHandler).Assembly);

                    break;

                case ServerType.World:
                    UchuServer.RegisterAssembly(typeof(CharacterHandler).Assembly);
                    await UchuServer.StartAsync(typeof(WorldInitializationHandler).Assembly);

                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }
            catch (Exception e)
            {
                Logger.Error(e);
            }

            Logger.Information("Exiting...");

            Console.ReadKey();
        }
示例#5
0
        public async Task ClientMailPacketHandler(ClientMailPacket packet, IRakConnection connection)
        {
            var player = UchuServer.FindPlayer(connection);

            if (player == default)
            {
                Logger.Error($"Could not find player for: {connection}");
                return;
            }

            switch (packet.Id)
            {
            case ClientMailPacketId.Send:
                await SendHandler(packet.MailStruct as MailSend, player);

                break;

            case ClientMailPacketId.DataRequest:
                await DataRequestHandler(player);

                break;

            case ClientMailPacketId.AttachmentCollected:
                await AttachmentCollectHandler(packet.MailStruct as MailAttachmentCollected, player);

                break;

            case ClientMailPacketId.Delete:
                await DeleteHandler(packet.MailStruct as MailDelete, player);

                break;

            case ClientMailPacketId.Read:
                await ReadHandler(packet.MailStruct as MailRead, player);

                break;

            case ClientMailPacketId.NotificationRequest:
                await NotificationRequestHandler(player);

                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
示例#6
0
        private static async Task ConfigureAsync(string config)
        {
            var serializer = new XmlSerializer(typeof(UchuConfiguration));

            if (!File.Exists(config))
            {
                throw new ArgumentException($"{config} config file does not exist.");
            }

            UchuConfiguration uchuConfiguration;

            await using (var fs = File.OpenRead(config))
            {
                UchuContextBase.Config = uchuConfiguration = (UchuConfiguration)serializer.Deserialize(fs);
            }

            var masterPath = Path.GetDirectoryName(config);

            SqliteContext.DatabasePath = Path.Combine(masterPath, "./Uchu.sqlite");

            var api = new ApiManager(uchuConfiguration.ApiConfig.Protocol, uchuConfiguration.ApiConfig.Domain);

            var instance = await api.RunCommandAsync <InstanceInfoResponse>(
                uchuConfiguration.ApiConfig.Port, $"instance/target?i={Id}"
                ).ConfigureAwait(false);

            if (!instance.Success)
            {
                Logger.Error(instance.FailedReason);

                throw new Exception(instance.FailedReason);
            }

            UchuServer = instance.Info.Type == (int)ServerType.World
                ? new WorldUchuServer(Id)
                : new UchuServer(Id);

            Console.Title = $"{(ServerType) instance.Info.Type}:{instance.Info.Port}";

            ServerType = (ServerType)instance.Info.Type;

            await UchuServer.ConfigureAsync(config);
        }
示例#7
0
        public async Task PositionHandler(PositionUpdatePacket packet, IRakConnection connection)
        {
            var player = UchuServer.FindPlayer(connection);

            if (player?.Transform == default)
            {
                return;
            }

            // The server is a slave to the position update packets it gets from the client right now.
            player.Transform.Position = packet.Position;
            player.Transform.Rotation = packet.Rotation;

            var physics = player.GetComponent <ControllablePhysicsComponent>();

            physics.HasPosition = true;

            physics.IsOnGround = packet.IsOnGround;
            physics.NegativeAngularVelocity = packet.NegativeAngularVelocity;

            physics.HasVelocity = (packet.Velocity != Vector3.Zero);

            physics.Velocity = packet.Velocity;

            physics.HasAngularVelocity = (packet.AngularVelocity != Vector3.Zero);

            physics.AngularVelocity = packet.AngularVelocity;

            physics.Platform = packet.PlatformObjectId;

            physics.PlatformPosition = packet.PlatformPosition;

            Zone.SendSerialization(player, player.Zone.Players.Where(
                                       p => p != player
                                       ).ToArray());

            player.UpdateView();

            await player.OnPositionUpdate.InvokeAsync(packet.Position, packet.Rotation);
        }
示例#8
0
        public Zone(ZoneInfo zoneInfo, UchuServer uchuServer, ushort instanceId = default, uint cloneId = default)
        {
            Zone       = this;
            ZoneInfo   = zoneInfo;
            UchuServer = uchuServer;
            InstanceId = instanceId;
            CloneId    = cloneId;

            EarlyPhysics  = new Event();
            LatePhysics   = new Event();
            OnPlayerLoad  = new Event <Player>();
            OnObject      = new Event <Object>();
            OnTick        = new Event();
            OnChatMessage = new Event <Player, string>();

            ScriptManager       = new ScriptManager(this);
            ManagedScriptEngine = new ManagedScriptEngine();
            UpdatedObjects      = new List <UpdatedObject>();
            ManagedObjects      = new List <Object>();
            SpawnedObjects      = new List <GameObject>();
            Simulation          = new PhysicsSimulation();

            Listen(OnDestroyed, () => { _running = false; });
        }
示例#9
0
        public async Task <string> ExecuteAs(string[] arguments, Player executor)
        {
            if (arguments.Length == default)
            {
                return("execute <playerName or *> <command>");
            }

            List <Player> players = new List <Player>();

            if (arguments[0] == "*")
            {
                foreach (var player in executor.Zone.Players)
                {
                    players.Add(player);
                }
            }
            else
            {
                // Todo: Fix this throwing an error if no player is found.
                var player = executor.Zone.Players.FirstOrDefault(p => p.Name == arguments[0]);
                if (player == default)
                {
                    return($"No player named {arguments[0]}");
                }
                players.Add(player);
            }

            await using var ctx = new UchuContext();
            var character = await ctx.Characters.Include(c => c.User).FirstAsync(
                c => c.Id == executor.Id
                );

            var message = new List <string>(arguments);

            message.RemoveAt(0);

            var command = string.Join(" ", message);

            if (!command.StartsWith('/'))
            {
                command = "/" + command;
            }

            if (!SocialHandler.ClientCommands.Contains(command.Split(" ").ElementAt(0)) && command.Split(" ").ElementAt(0) != "/execute" && command.Length > 1)
            {
                foreach (Player player in players)
                {
                    player.SendChatMessage("You feel a magical power...", PlayerChatChannel.Normal);
                    var response = await UchuServer.HandleCommandAsync(
                        command,
                        player,
                        (GameMasterLevel)character.User.GameMasterLevel
                        );

                    if (!string.IsNullOrWhiteSpace(response))
                    {
                        //executor.SendChatMessage($"{player.Name}: {response}", PlayerChatChannel.Normal);
                        player.SendChatMessage(response, PlayerChatChannel.Normal);
                    }
                }

                return($"Executed \"{command}\" as {players.Count} {(players.Count == 1 ? "person" : "people")}");
            }
            else
            {
                return($"Unable to execute \"{command}\"");
            }
        }
示例#10
0
 public async Task RoutedHandler(ClientRoutedPacket packet, IRakConnection connection)
 {
     await UchuServer.HandlePacketAsync(connection.EndPoint, packet.Packet, Reliability.ReliableOrdered);
 }
示例#11
0
 public InstanceCommands(UchuServer uchuServer)
 {
     UchuServer = uchuServer;
 }
示例#12
0
        public async Task ParseChatMessageHandler(ParseChatMessage message, Player player)
        {
            try
            {
                await player.Zone.OnChatMessage.InvokeAsync(player, message.Message);
            }
            catch
            {
                // Something went wrong with event
            }

            await using var ctx = new UchuContext();

            var character = await ctx.Characters.Include(c => c.User).FirstAsync(
                c => c.Id == player.Id
                );

            if (message.Message.StartsWith('/') && !ClientCommands.Contains(message.Message.Split(" ").ElementAt(0)))
            {
                if (ClientCommands.Contains(message.Message.Split(" ").ElementAt(0)))
                {
                    return;
                }

                var response = await UchuServer.HandleCommandAsync(
                    message.Message,
                    player,
                    (GameMasterLevel)character.User.GameMasterLevel
                    );

                if (!string.IsNullOrWhiteSpace(response))
                {
                    player.SendChatMessage(response, PlayerChatChannel.Normal);
                }
                return;
            }

            Console.WriteLine($"Message: {message.Message}");

            if (((WorldUchuServer)UchuServer).Whitelist.CheckPhrase(message.Message).Any())
            {
                return;
            }

            var transcript = new ChatTranscript
            {
                Author   = character.Id,
                Message  = message.Message,
                Receiver = 0,
                SentTime = DateTime.Now
            };

            await ctx.ChatTranscript.AddAsync(transcript);

            await ctx.SaveChangesAsync();

            foreach (var zonePlayer in player.Zone.Players)
            {
                zonePlayer.SendChatMessage(message.Message, PlayerChatChannel.Normal, player);
            }
        }
示例#13
0
 public void SetServer(UchuServer uchuServer)
 {
     lock (_lock)
         UchuServer = uchuServer;
 }
示例#14
0
        public async Task Start(string[] args)
        {
            if (args.Length != 2)
            {
                throw new ArgumentException("Expected 2 argument.");
            }

            if (!Guid.TryParse(args[0], out var id))
            {
                throw new ArgumentException($"{args[0]} is not a valid GUID");
            }

            Id = id;
            try {
                await ConfigureAsync(args[1]).ConfigureAwait(false);

                Logger.Debug($"Process ID: {Process.GetCurrentProcess().Id}");

                switch (ServerType)
                {
                case ServerType.Authentication:
#if DEBUG
                    if (!UchuServer.Config.DebugConfig.StartInstancesAsThreads)
#endif
                    Logger.SetServerTypeInformation("Auth");
                    await UchuServer.StartAsync(typeof(LoginHandler).Assembly, true);

                    break;

                case ServerType.Character:
#if DEBUG
                    if (!UchuServer.Config.DebugConfig.StartInstancesAsThreads)
#endif
                    Logger.SetServerTypeInformation("Char");
                    await UchuServer.StartAsync(typeof(CharacterHandler).Assembly);

                    break;

                case ServerType.World:
                    UchuServer.RegisterAssembly(typeof(CharacterHandler).Assembly);
                    await UchuServer.StartAsync(typeof(WorldInitializationHandler).Assembly);

                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }
            catch (Exception e)
            {
                if (ServerType == ServerType.Authentication || ServerType == ServerType.Character)
                {
                    // Server cannot function without auth or char; exit
                    await UchuServer.Api.RunCommandAsync <Task>(
                        UchuServer.MasterApi,
                        $"master/decommission?message=Could not start {ServerType} server on port {UchuServer.Port}: {e.Message}. Try specifying another port in config.xml."
                        ).ConfigureAwait(false);
                }
                else if (ServerType == ServerType.World)
                {
                    Console.WriteLine($"Could not start {ServerType} server on port {UchuServer.Port}: {e.Message}. Try specifying more WorldPort entries under Networking in config.xml.");
                }

                Environment.Exit(1);
            }

            Logger.Information("Exiting...");

            Console.ReadKey();
        }