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) )); }
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); }
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 }); }
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(); }
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(); } }
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); }
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); }
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; }); }
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}\""); } }
public async Task RoutedHandler(ClientRoutedPacket packet, IRakConnection connection) { await UchuServer.HandlePacketAsync(connection.EndPoint, packet.Packet, Reliability.ReliableOrdered); }
public InstanceCommands(UchuServer uchuServer) { UchuServer = uchuServer; }
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); } }
public void SetServer(UchuServer uchuServer) { lock (_lock) UchuServer = uchuServer; }
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(); }