public async Task ClientLoadCompleteHandler(ClientLoadCompletePacket packet, IRakConnection connection) { Logger.Information($"{connection.EndPoint}'s client load completed..."); var session = UchuServer.SessionCache.GetSession(connection.EndPoint); await using var ctx = new UchuContext(); var character = await ctx.Characters .Include(c => c.Flags) .Include(c => c.Items) .Include(c => c.User) .Include(c => c.Missions) .ThenInclude(m => m.Tasks) .ThenInclude(m => m.Values) .SingleAsync(c => c.Id == session.CharacterId); var zoneId = (ZoneId)character.LastZone; if (zoneId == 0) { zoneId = 1000; character.LastZone = zoneId; await ctx.SaveChangesAsync(); } Logger.Information("[55%] Setting session zone."); UchuServer.SessionCache.SetZone(connection.EndPoint, zoneId); // Zone should already be initialized at this point. Logger.Information("[55%] Getting zone from worldserver."); var zone = await((WorldUchuServer)UchuServer).GetZoneAsync(zoneId); // Send the character init XML data for this world to the client Logger.Information("[55%] Sending XML client info."); await SendCharacterXmlDataToClient(character, connection, session); Logger.Information("[55%] Constructing player."); var player = await Player.ConstructAsync(character, connection, zone); Logger.Information("[55%] Checking rocket landing conditions."); if (character.LandingByRocket) { Logger.Information("[55%] Player landed by rocket, saving changes."); character.LandingByRocket = false; await ctx.SaveChangesAsync(); } Logger.Information("[55%] Player is ready to join world."); player.Message(new PlayerReadyMessage { Associate = player }); Logger.Information("[55%] Server is done loading object."); player.Message(new DoneLoadingObjectsMessage { Associate = player }); }
public async Task <object> PardonAccount(string accountName) { var response = new AccountPardonResponse(); if (string.IsNullOrWhiteSpace(accountName)) { response.FailedReason = "username null"; return(response); } await using (var ctx = new UchuContext()) { var user = await ctx.Users.FirstOrDefaultAsync(u => string.Equals(u.Username.ToUpper(), accountName.ToUpper())); if (user == default) { response.FailedReason = "not found"; return(response); } user.Banned = false; user.BannedReason = null; await ctx.SaveChangesAsync(); response.Success = true; response.Username = user.Username; } return(response); }
public async Task <string> SetGameMasterLevel(string[] arguments) { if (arguments.Length != 2) { return("gamemaster <username> <level>"); } var username = arguments[0]; await using var ctx = new UchuContext(); var user = await ctx.Users.FirstOrDefaultAsync(u => u.Username == username); if (user == default) { return($"No user with the username of: {username}"); } if (!Enum.TryParse <GameMasterLevel>(arguments[1], out var level)) { return("Invalid <level>"); } user.GameMasterLevel = (int)level; await ctx.SaveChangesAsync(); return$ "Successfully set {user.Username}'s Game Master " + $"level to {(GameMasterLevel) user.GameMasterLevel}"; }
public async Task RenameCharacter(CharacterRenameRequest packet, IRakConnection connection) { var session = Server.SessionCache.GetSession(connection.EndPoint); await using var ctx = new UchuContext(); if (ctx.Characters.Any(c => c.Name == packet.Name || c.CustomName == packet.Name)) { connection.Send(new CharacterRenameResponse { ResponseId = CharacterRenamingResponse.NameAlreadyInUse } ); return; } var chr = await ctx.Characters.FindAsync(packet.CharacterId); chr.CustomName = packet.Name; chr.NameRejected = false; chr.LastActivity = DateTimeOffset.Now.ToUnixTimeSeconds(); await ctx.SaveChangesAsync(); connection.Send(new CharacterRenameResponse { ResponseId = CharacterRenamingResponse.Success } ); await SendCharacterList(connection, session.UserId); }
public async Task JoinWorld(JoinWorldRequest packet, IRakConnection connection) { UchuServer.SessionCache.SetCharacter(connection.EndPoint, packet.CharacterId); await using var ctx = new UchuContext(); var character = await ctx.Characters.FirstAsync(c => c.Id == packet.CharacterId); character.LastActivity = DateTimeOffset.Now.ToUnixTimeSeconds(); await ctx.SaveChangesAsync(); var zone = (ZoneId)character.LastZone; var requestZone = (ZoneId)(zone == 0 ? 1000 : zone); // We don't want to lock up the server on a world server request, as it may take time. var _ = Task.Run(async() => { // Request world server. var server = await ServerHelper.RequestWorldServerAsync(UchuServer, requestZone); if (server == default) { // If there's no server available, error var session = UchuServer.SessionCache.GetSession(connection.EndPoint); await SendCharacterList(connection, session.UserId); return; } // Send to world server. connection.Send(new ServerRedirectionPacket { Address = UchuServer.Host, Port = (ushort)server.Port }); }); }
public async Task RenameCharacter(CharacterRenameRequest packet, IRakConnection connection) { var session = UchuServer.SessionCache.GetSession(connection.EndPoint); await using var ctx = new UchuContext(); // Check if the name already exists and return proper response if so if (ctx.Characters.Any(c => c.Name == packet.Name || c.CustomName == packet.Name)) { connection.Send(new CharacterRenameResponse { ResponseId = CharacterRenamingResponse.NameAlreadyInUse } ); return; } // If the name is free, update accordingly and notify the client var chr = await ctx.Characters.FindAsync(packet.CharacterId); chr.CustomName = packet.Name; chr.NameRejected = false; chr.LastActivity = DateTimeOffset.Now.ToUnixTimeSeconds(); await ctx.SaveChangesAsync(); connection.Send(new CharacterRenameResponse { ResponseId = CharacterRenamingResponse.Success } ); await SendCharacterList(connection, session.UserId); }
public async Task <string> BanUser(string[] arguments) { if (arguments.Length != 2) { return($"{arguments[0]} <name> <reason>"); } var name = arguments[0]; var reason = arguments[1]; await using var ctx = new UchuContext(); var user = await ctx.Users.FirstOrDefaultAsync(u => u.Username == name); if (user == null) { return($"No user with the username of: {name}"); } user.Banned = true; user.BannedReason = reason; await ctx.SaveChangesAsync(); return($"Successfully banned {name}!"); }
public static async Task DeleteHandler(MailDelete packet, Player player) { var response = new DeleteConfirm { MailId = packet.MailId }; await using var ctx = new UchuContext(); var mail = await ctx.Mails.FirstOrDefaultAsync(m => m.Id == packet.MailId); if (mail == default) { response.Code = MailDeleteCode.MailNotFound; goto sendResponse; } response.Code = MailDeleteCode.Success; ctx.Mails.Remove(mail); sendResponse: await ctx.SaveChangesAsync(); player.Message(new ServerMailPacket { Id = ServerMailPacketId.DeleteConfirm, MailStruct = response }); }
public static async Task <string> PardonUser(string[] arguments) { if (arguments == null) { throw new ArgumentNullException(nameof(arguments), ResourceStrings.StandardCommandHandler_PardonUser_ArgumentsNullException); } if (arguments.Length != 1) { return($"{arguments[0]} <name>"); } var name = arguments[0]; await using var ctx = new UchuContext(); var user = await ctx.Users.FirstOrDefaultAsync(u => string.Equals(u.Username.ToUpper(), name.ToUpper())) .ConfigureAwait(false); if (user == null) { return($"No user with the username of: {name}"); } user.Banned = false; user.BannedReason = null; await ctx.SaveChangesAsync().ConfigureAwait(false); return($"Successfully pardoned {name}!"); }
public async Task <object> DeleteAccount(string accountName) { var response = new AccountDeleteResponse(); if (string.IsNullOrWhiteSpace(accountName)) { response.FailedReason = "username null"; return(response); } await using (var ctx = new UchuContext()) { var user = await ctx.Users.FirstOrDefaultAsync(u => u.Username == accountName); if (user == default) { response.FailedReason = "not found"; return(response); } ctx.Users.Remove(user); await ctx.SaveChangesAsync(); response.Success = true; response.Username = user.Username; } return(response); }
public static async Task <string> BanUser(string[] arguments) { if (arguments == null) { throw new ArgumentNullException(nameof(arguments), ResourceStrings.StandardCommandHandler_BanUser_ArgumentsNullException); } if (arguments.Length != 2) { return($"{arguments[0]} <name> <reason>"); } var name = arguments[0]; var reason = arguments[1]; await using var ctx = new UchuContext(); var user = await ctx.Users.FirstOrDefaultAsync(u => u.Username == name) .ConfigureAwait(false); if (user == null) { return($"No user with the username of: {name}"); } user.Banned = true; user.BannedReason = reason; await ctx.SaveChangesAsync().ConfigureAwait(false); return($"Successfully banned {name}!"); }
public async Task OnInteract(Player player) { var rocket = player.GetComponent <InventoryManagerComponent>()[InventoryType.Models].Items.FirstOrDefault( item => item.Lot == Lot.ModularRocket ); if (rocket == default) { Logger.Error($"Could not find a valid rocket for {player}"); return; } rocket.WorldState = ObjectWorldState.Attached; player.Message(new FireClientEventMessage { Associate = GameObject, Arguments = "RocketEquipped", Target = rocket, Sender = player }); await using var ctx = new UchuContext(); var character = await ctx.Characters.FirstAsync(c => c.Id == player.Id); character.LandingByRocket = true; await ctx.SaveChangesAsync(); }
/// <summary> /// Saves the game object by finding all <see cref="ISavableComponent"/> components and calling /// <see cref="SaveAsync"/> on them. /// </summary> /// <param name="continueSaving">Whether to allow saves after this save</param> /// <remarks> /// Note that once continueSaving has been set to false, this behavior can not be undone and the /// component is rendered useless. This is to ensure that after an important event (the player leaving the server) /// stuff is saved no more than once to prevent corruptions. /// </remarks> public async Task SaveAsync(bool continueSaving = true) { if (!_savable) { return; } await _lock.WaitAsync(); try { await using var uchuContext = new UchuContext(); foreach (var savableComponent in GameObject .GetAllComponents().Where(c => c is ISavableComponent)) { await((ISavableComponent)savableComponent).SaveAsync(uchuContext); } // This check has to be done twice in case of race conditions if (_savable) { await uchuContext.SaveChangesAsync(); } } finally { if (!continueSaving) { _savable = false; } _lock.Release(); } }
public static async Task <string> ApproveUsernames(string[] arguments) { if (arguments == null) { throw new ArgumentNullException(nameof(arguments), ResourceStrings.StandardCommandHandler_ApproveUsername_ArgumentsNullException); } await using var ctx = new UchuContext(); if (arguments.Length == 0 || arguments[0].ToLower() == "*" || string.IsNullOrEmpty(arguments[0])) { var unApproved = ctx.Characters.Where(c => !c.NameRejected && c.Name != c.CustomName && !string.IsNullOrEmpty(c.CustomName)); if (arguments.Length != 1 || arguments[0] != "*") { return(string.Join("\n", unApproved.Select(s => s.CustomName) ) + "\napprove <name> / *"); } foreach (var character in unApproved) { character.Name = character.CustomName; character.CustomName = ""; } await ctx.SaveChangesAsync().ConfigureAwait(false); return("Successfully approved all names!"); } var selectedCharacter = await ctx.Characters.FirstOrDefaultAsync( c => c.CustomName == arguments[0] && !c.NameRejected ).ConfigureAwait(false); if (selectedCharacter == null) { return($"No unapproved character with name: \"{arguments[0]}\""); } selectedCharacter.Name = selectedCharacter.CustomName; selectedCharacter.CustomName = ""; await ctx.SaveChangesAsync().ConfigureAwait(false); return($"Successfully approved \"{selectedCharacter.Name}\"!"); }
public override Task LoadAsync() { Listen(Zone.OnPlayerLoad, player => { Listen(player.OnFireServerEvent, async(EventName, message) => { if (EventName == "ZonePlayer") { var launchpad = message.Associate.GetComponent <RocketLaunchpadComponent>(); await using var cdClient = new CdClientContext(); var id = launchpad.GameObject.Lot.GetComponentId(ComponentId.RocketLaunchComponent); var launchpadComponent = await cdClient.RocketLaunchpadControlComponentTable.FirstOrDefaultAsync( r => r.Id == id ); if (launchpadComponent == default) { return; } await using var ctx = new UchuContext(); var character = await ctx.Characters.FirstAsync(c => c.Id == player.Id); character.LaunchedRocketFrom = Zone.ZoneId; await ctx.SaveChangesAsync(); if (launchpadComponent.TargetZone != null) { var target = (ZoneId)launchpadComponent.TargetZone; // // We don't want to lock up the server on a world server request, as it may take time. // var _ = Task.Run(async() => { var success = await player.SendToWorldAsync(target); if (!success) { player.SendChatMessage($"Failed to transfer to {target}, please try later."); } }); } } }); return(Task.CompletedTask); }); return(Task.CompletedTask); }
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 ); Console.WriteLine($"Message: {message.Message}"); if (message.Message.StartsWith('/')) { var response = await Server.HandleCommandAsync( message.Message, player, (GameMasterLevel)character.User.GameMasterLevel ); if (!string.IsNullOrWhiteSpace(response)) { player.SendChatMessage(response, PlayerChatChannel.Normal); } return; } if (((WorldServer)Server).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 async Task <object> CreateAccount(string accountName, string accountPassword) { var response = new AccountCreationResponse(); if (string.IsNullOrWhiteSpace(accountName)) { response.FailedReason = "username null"; return(response); } if (string.IsNullOrWhiteSpace(accountPassword)) { response.FailedReason = "password null"; return(response); } await using (var ctx = new UchuContext()) { var duplicate = await ctx.Users.Where(u => !u.Sso).AnyAsync(u => u.Username == accountName); if (duplicate) { response.FailedReason = "duplicate username"; return(response); } var password = BCrypt.Net.BCrypt.EnhancedHashPassword(accountPassword); await ctx.Users.AddAsync(new User { Username = accountName, Password = password }); await ctx.SaveChangesAsync(); } await using (var ctx = new UchuContext()) { var user = await ctx.Users.FirstOrDefaultAsync(u => u.Username == accountName); if (user == default) { return(response); } response.Success = true; response.Id = user.Id; response.Username = user.Username; response.Hash = user.Password; } return(response); }
private static async Task UpdateEquipState(ObjectId id, bool state) { await using var ctx = new UchuContext(); var item = await ctx.InventoryItems.FirstOrDefaultAsync(i => i.Id == id); item.IsEquipped = state; await ctx.SaveChangesAsync(); }
private async Task RemoveFromInventoryAsync() { await using var ctx = new UchuContext(); var item = await ctx.InventoryItems.FirstAsync(i => i.Id == Id); item.Character.Items.Remove(item); await ctx.SaveChangesAsync(); }
public async Task BindAsync() { await using var ctx = new UchuContext(); var item = await ctx.InventoryItems.FirstAsync(i => i.Id == Id); item.IsBound = true; await ctx.SaveChangesAsync(); }
public async Task SetLastCustomBuildHandler(SetLastCustomBuildMessage message, Player player) { await using var ctx = new UchuContext(); var character = await ctx.Characters.FirstAsync(c => c.Id == player.Id); character.Rocket = message.Tokens; await ctx.SaveChangesAsync(); }
public async Task <string> ApproveUsernames(string[] arguments) { await using var ctx = new UchuContext(); if (arguments.Length == 0 || arguments[0].ToLower() == "all") { var unApproved = ctx.Characters.Where(c => !c.NameRejected && c.Name != c.CustomName && !string.IsNullOrEmpty(c.CustomName)); if (arguments.Length != 1 || arguments[0] != "all") { return(string.Join("\n", unApproved.Select(s => s.CustomName) ) + "\napprove <name> / all"); } foreach (var character in unApproved) { character.Name = character.CustomName; character.CustomName = ""; } await ctx.SaveChangesAsync(); return("Successfully approved all names!"); } var selectedCharacter = await ctx.Characters.FirstOrDefaultAsync( c => c.CustomName == arguments[1] && !c.NameRejected ); if (selectedCharacter == null) { return($"No unapproved character with name: \"{arguments[0]}\""); } selectedCharacter.Name = selectedCharacter.CustomName; selectedCharacter.CustomName = ""; await ctx.SaveChangesAsync(); return($"Successfully approved \"{selectedCharacter.Name}\"!"); }
public async Task JoinWorld(JoinWorldRequest packet, IRakConnection connection) { Server.SessionCache.SetCharacter(connection.EndPoint, packet.CharacterId); await using var ctx = new UchuContext(); var character = await ctx.Characters.FirstAsync(c => c.CharacterId == packet.CharacterId); character.LastActivity = DateTimeOffset.Now.ToUnixTimeSeconds(); await ctx.SaveChangesAsync(); var zone = (ZoneId)character.LastZone; var requestZone = zone == ZoneId.VentureExplorerCinematic ? ZoneId.VentureExplorer : zone; // // We don't want to lock up the server on a world server request, as it may take time. // var _ = Task.Run(async() => { // // Request world server. // var server = await ServerHelper.RequestWorldServerAsync(requestZone); if (server == default) { // // Error // var session = Server.SessionCache.GetSession(connection.EndPoint); await SendCharacterList(connection, session.UserId); return; } // // Send to world server. // connection.Send(new ServerRedirectionPacket { Address = Server.GetHost(), Port = (ushort)server.Port }); }); }
public async Task StartAsync() { await using var ctx = new UchuContext(); await using var cdClient = new CdClientContext(); // // Setup new mission // var mission = await ctx.Missions.FirstOrDefaultAsync( m => m.CharacterId == Player.Id && m.MissionId == MissionId ); var tasks = await cdClient.MissionTasksTable.Where( t => t.Id == MissionId ).ToArrayAsync(); if (mission != default) { return; } await ctx.Missions.AddAsync(new Mission { CharacterId = Player.Id, MissionId = MissionId, Tasks = tasks.Select(task => new MissionTask { TaskId = task.Uid ?? 0 }).ToList() }); await ctx.SaveChangesAsync(); await UpdateMissionStateAsync(MissionState.Active); var clientMission = await cdClient.MissionsTable.FirstAsync( m => m.Id == MissionId ); MessageMissionTypeState(MissionLockState.New, clientMission.Definedsubtype, clientMission.Definedtype); await CatchupAsync(); if (Player.TryGetComponent <MissionInventoryComponent>(out var missionInventory)) { await missionInventory.OnAcceptMission.InvokeAsync(this); } }
private static async Task ClearProxiesAsync(ObjectId id) { await using var ctx = new UchuContext(); var proxies = await ctx.InventoryItems.Where( i => i.ParentId == id ).ToArrayAsync().ConfigureAwait(false); foreach (var proxy in proxies) { ctx.InventoryItems.Remove(proxy); } await ctx.SaveChangesAsync(); }
public async Task <object> AdminAccount(string accountName, string level) { var response = new AccountAdminResponse(); if (string.IsNullOrWhiteSpace(accountName)) { response.FailedReason = "username null"; return(response); } if (string.IsNullOrWhiteSpace(level)) { response.FailedReason = "level null"; return(response); } await using (var ctx = new UchuContext()) { var user = await ctx.Users.FirstOrDefaultAsync(u => string.Equals(u.Username.ToUpper(), accountName.ToUpper())); if (user == default) { response.FailedReason = "not found"; return(response); } if (!Enum.TryParse <GameMasterLevel>(level, out var gameMasterLevel) || !Enum.IsDefined(typeof(GameMasterLevel), gameMasterLevel)) { response.FailedReason = "invalid level"; return(response); } user.GameMasterLevel = (int)gameMasterLevel; await ctx.SaveChangesAsync(); response.Success = true; response.Username = user.Username; response.Level = (int)gameMasterLevel; } return(response); }
private async Task UpdateCountAsync(uint count) { if (count >= Count) { AddCount(count); } else { RemoveCount(count); } if (count > 0) { return; } await using var ctx = new UchuContext(); var item = await ctx.InventoryItems.FirstOrDefaultAsync( i => i.Id == Id ); if (item == default) { return; } if (await IsEquippedAsync()) { await UnEquipAsync(); } ctx.InventoryItems.Remove(item); await ctx.SaveChangesAsync(); // Disassemble item. if (LegoDataDictionary.FromString(item.ExtraInfo).TryGetValue("assemblyPartLOTs", out var list)) { foreach (var part in (LegoDataList)list) { await Inventory.ManagerComponent.AddItemAsync((int)part, 1); } } Destroy(this); }
public static async Task AttachmentCollectHandler(MailAttachmentCollected packet, Player player) { var response = new AttachmentCollectConfirm { MailId = packet.MailId }; await using var ctx = new UchuContext(); var mail = await ctx.Mails.FirstOrDefaultAsync(m => m.Id == packet.MailId); if (mail == default) { response.Code = MailAttachmentCollectCode.MailForFound; goto sendResponse; } if (mail.AttachmentLot == -1 || mail.AttachmentCount == default) { response.Code = MailAttachmentCollectCode.InvalidAttachment; goto sendResponse; } await player.GetComponent <InventoryManagerComponent>().AddItemAsync( mail.AttachmentLot, mail.AttachmentCount ); mail.AttachmentLot = -1; mail.AttachmentCount = 0; player.Currency += (long)mail.AttachmentCurrency; response.Code = MailAttachmentCollectCode.Success; sendResponse: await ctx.SaveChangesAsync(); player.Message(new ServerMailPacket { Id = ServerMailPacketId.AttachmentCollectedConfirm, MailStruct = response }); }
private static async Task <ObjectId[]> GenerateProxiesAsync(ObjectId id) { var item = await id.FindItemAsync(); if (item == default) { return(new ObjectId[0]); } var proxies = await ParseProxyItemsAsync(item.Lot); await using var ctx = new UchuContext(); var references = new ObjectId[proxies.Length]; for (var index = 0; index < proxies.Length; index++) { var proxy = proxies[index]; var instance = await ctx.InventoryItems.FirstOrDefaultAsync( i => i.ParentId == id && i.Lot == proxy ).ConfigureAwait(false); if (instance == default) { instance = new InventoryItem { Id = ObjectId.Standalone, Lot = proxy, Count = 0, Slot = -1, InventoryType = (int)InventoryType.Hidden, CharacterId = item.CharacterId, ParentId = id }; await ctx.InventoryItems.AddAsync(instance); await ctx.SaveChangesAsync(); } references[index] = instance.Id; } return(references); }
public async Task AddProgressAsync(float value) { await using var ctx = new UchuContext(); var mission = await ctx.Missions .Include(m => m.Tasks) .ThenInclude(t => t.Values) .FirstAsync(m => m.MissionId == MissionId && m.CharacterId == Player.ObjectId); var task = mission.Tasks.First(m => m.TaskId == TaskId); task.Add(value); await ctx.SaveChangesAsync(); await MessageUpdateMissionTaskAsync(new[] { (float)task.ValueArray().Length }); }