示例#1
0
        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}!");
        }
示例#2
0
        public static string RemoveUser(string[] arguments)
        {
            if (arguments == null)
            {
                throw new ArgumentNullException(nameof(arguments),
                                                ResourceStrings.StandardCommandHandler_RemoveUser_ArgumentsNullException);
            }

            if (arguments.Length != 1)
            {
                return("removeuser <name>");
            }

            var name = arguments[0];

            using var ctx = new UchuContext();
            var user = ctx.Users.FirstOrDefault(u => String.Equals(u.Username.ToUpper(), name.ToUpper()));

            if (user == null)
            {
                return($"No user with the username of: {name}");
            }

            Console.Write(ResourceStrings.StandardCommandHandler_RemoveUser_ConfirmationMessage);
            if (Console.ReadLine() != name)
            {
                return("Deletion aborted");
            }

            ctx.Users.Remove(user);
            ctx.SaveChanges();

            return($"Successfully deleted user: {name}");
        }
示例#3
0
        public static async Task SendGuildInformationAsync(Player player)
        {
            await using var ctx = new UchuContext();

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

            var guild = await ctx.Guilds.FirstOrDefaultAsync(g => g.Id == character.GuildId);

            if (guild == default)
            {
                player.CentralNoticeGui("You are not a member of a guild!");

                return;
            }

            await UiHelper.SetGuildNameAsync(player, guild.Name);

            await player.MessageGuiAsync("ClearGuildMembers");

            var members = await ctx.Characters.Where(c => c.GuildId == guild.Id).ToArrayAsync();

            var index = 0;

            foreach (var member in members)
            {
                var memberPlayer = player.Zone.Players.FirstOrDefault(p => p.Id == member.Id);

                await UiHelper.AddGuildMemberAsync(player, index ++, new GuildMember
                {
                    Name   = member.Name,
                    Online = memberPlayer != default,
                    Rank   = guild.CreatorId == member.Id ? "Owner" : "Member",
                    Zone   = ((ZoneId)member.LastZone).ToString()
                });
示例#4
0
        /// <summary>
        /// Loads specific uchu context information about the mission.
        /// </summary>
        private async Task LoadInstanceAsync(UchuContext context)
        {
            // Mission instance information
            var mission = await context.Missions
                          .Include(m => m.Tasks)
                          .ThenInclude(t => t.Values)
                          .FirstOrDefaultAsync(m => m.CharacterId == Player.Id && m.MissionId == MissionId);

            // Start the mission if it hasn't been started, otherwise load the database information
            if (mission != default)
            {
                State           = (MissionState)mission.State;
                CompletionCount = mission.CompletionCount;
                LastCompletion  = mission.LastCompletion;

                foreach (var task in Tasks)
                {
                    var taskInstance = mission.Tasks.FirstOrDefault(t => t.TaskId == task.TaskId);
                    if (taskInstance == default)
                    {
                        continue;
                    }

                    task.LoadInstance(taskInstance);
                }
            }
        }
示例#5
0
        public async Task <object> CharacterList(string id)
        {
            var response = new CharacterListResponse();

            if (!long.TryParse(id, out var userId))
            {
                response.FailedReason = "invalid id";

                return(response);
            }

            await using var ctx = new UchuContext();

            var user = await ctx.Users.FirstOrDefaultAsync(u => u.Id == userId);

            if (user == default)
            {
                response.FailedReason = "not found";

                return(response);
            }

            var characters = await ctx.Characters.Where(c => c.UserId == user.Id).ToArrayAsync();

            response.Success = true;

            response.UserId = userId;

            response.Characters = characters.Select(c => c.Id.ToString()).ToList();

            return(response);
        }
示例#6
0
        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}!");
        }
示例#7
0
        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();
        }
示例#8
0
        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
            });
        }
示例#9
0
        internal Inventory(InventoryType inventoryType, InventoryManagerComponent managerComponent)
        {
            InventoryType    = inventoryType;
            ManagerComponent = managerComponent;

            using var ctx = new UchuContext();
            var playerCharacter = ctx.Characters
                                  .Include(c => c.Items)
                                  .First(c => c.CharacterId == managerComponent.GameObject.ObjectId);

            var inventoryItems = playerCharacter.Items
                                 .Where(item => (InventoryType)item.InventoryType == inventoryType)
                                 .ToList();

            _items = inventoryItems.Select(
                i => Item.Instantiate(i.InventoryItemId, this)
                ).Where(item => !ReferenceEquals(item, default)).ToList();

            _size = inventoryType != InventoryType.Items ? 1000 : playerCharacter.InventorySize;

            foreach (var item in _items)
            {
                Object.Start(item);
            }
        }
 public Mission[] GetMissions()
 {
     using var ctx = new UchuContext();
     return(ctx.Missions.Include(m => m.Tasks).ThenInclude(m => m.Values).Where(
                m => m.Character.CharacterId == GameObject.ObjectId
                ).ToArray());
 }
示例#11
0
        public async Task LoadAsync()
        {
            await using var ctx = new UchuContext();

            var missions = await ctx.Missions.Where(
                m => m.CharacterId == GameObject.Id
                ).ToArrayAsync();

            MissionInstances = new List <MissionInstance>();

            Player player = GameObject as Player;

            foreach (var mission in missions)
            {
                var instance = new MissionInstance(player, mission.MissionId);

                MissionInstances.Add(instance);

                await instance.LoadAsync();
            }

            Listen(player.OnRespondToMission, async(MissionID, Reciever, RewardLOT) =>
            {
                await RespondToMissionAsync(MissionID, Reciever, RewardLOT);
            });
        }
示例#12
0
        public string RemoveUser(string[] arguments)
        {
            if (arguments.Length != 1)
            {
                return("removeuser <name>");
            }

            var name = arguments[0];

            using var ctx = new UchuContext();
            var user = ctx.Users.FirstOrDefault(u => u.Username == name);

            if (user == null)
            {
                return($"No user with the username of: {name}");
            }

            Console.Write("Write the username again to confirm deletion: ");
            if (Console.ReadLine() != name)
            {
                return("Deletion aborted");
            }

            ctx.Users.Remove(user);
            ctx.SaveChanges();

            return($"Successfully deleted user: {name}");
        }
        /// <summary>
        /// Loads all player missions, combining the cd client and uchu database into mission instances
        /// </summary>
        private async Task LoadAsync()
        {
            if (GameObject is Player player)
            {
                await using var uchuContext = new UchuContext();

                // On load, load all the missions from database and store them in memory
                var missions = await uchuContext.Missions.Where(
                    m => m.CharacterId == GameObject.Id
                    ).ToArrayAsync();

                foreach (var mission in missions)
                {
                    var instance = new MissionInstance(mission.MissionId, player);
                    await instance.LoadAsync(uchuContext);

                    lock (Missions)
                    {
                        Missions.Add(instance);
                    }
                }
                this._loaded = true;

                Listen(player.OnRespondToMission, async(missionId, receiver, rewardLot) =>
                {
                    await RespondToMissionAsync(missionId, receiver, rewardLot);
                });
            }
        }
示例#14
0
        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);
        }
示例#15
0
        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}";
        }
示例#16
0
        /// <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();
            }
        }
示例#17
0
        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);
        }
示例#18
0
        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
                });
            });
        }
示例#19
0
        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);
        }
        /// <summary>
        /// Saves the mission inventory of the player
        /// </summary>
        /// <param name="context">The database context to save to</param>
        public async Task SaveAsync(UchuContext context)
        {
            if (!this._loaded)
            {
                return;
            }
            var character = await context.Characters.Where(c => c.Id == GameObject.Id)
                            .Include(c => c.Missions)
                            .ThenInclude(m => m.Tasks)
                            .ThenInclude(t => t.Values)
                            .FirstAsync();

            foreach (var mission in AllMissions)
            {
                var savedMission = character.Missions
                                   .FirstOrDefault(m => m.MissionId == mission.MissionId);

                if (savedMission == default)
                {
                    character.Missions.Add(CreateMissionFromMissionInstance(character, mission));
                }
                else
                {
                    UpdateMissionFromMissionInstance(savedMission, mission);
                }
            }

            Logger.Debug($"Saved mission inventory for {GameObject}");
        }
示例#21
0
 public Mission[] GetCompletedMissions()
 {
     using var ctx = new UchuContext();
     return(ctx.Missions.Include(m => m.Tasks).ThenInclude(m => m.Values).Where(
                m => m.Character.Id == GameObject.Id && m.CompletionCount > 0
                ).ToArray());
 }
示例#22
0
        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}!");
        }
示例#23
0
        private Player()
        {
            Listen(OnStart, async() =>
            {
                Connection.Disconnected += reason =>
                {
                    Connection = default;

                    Destroy(this);

                    return(Task.CompletedTask);
                };

                if (TryGetComponent <DestructibleComponent>(out var destructibleComponent))
                {
                    destructibleComponent.OnResurrect.AddListener(() => { GetComponent <Stats>().Imagination = 6; });
                }

                await using var ctx = new UchuContext();

                var character = await ctx.Characters
                                .Include(c => c.UnlockedEmotes)
                                .FirstAsync(c => c.CharacterId == ObjectId);

                foreach (var unlockedEmote in character.UnlockedEmotes)
                {
                    await UnlockEmoteAsync(unlockedEmote.EmoteId);
                }
            });
示例#24
0
        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);
        }
示例#25
0
        public async Task <object> AccountInfo(string accountName)
        {
            var response = new AccountInfoResponse();

            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);
                }

                response.Success      = true;
                response.Username     = user.Username;
                response.Hash         = user.Password;
                response.Id           = user.Id;
                response.Banned       = user.Banned;
                response.BannedReason = user.BannedReason;
                response.Level        = user.GameMasterLevel;
            }

            return(response);
        }
示例#26
0
        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
            });
        }
示例#27
0
        public async Task <bool> HasMissionAsync(int id)
        {
            await using var ctx = new UchuContext();

            return(await ctx.Missions.AnyAsync(
                       m => m.CharacterId == GameObject.Id && m.MissionId == id
                       ));
        }
示例#28
0
        public async Task <bool> HasCompletedAsync(int id)
        {
            await using var ctx = new UchuContext();

            return(await ctx.Missions.AnyAsync(
                       m => m.CharacterId == GameObject.Id && m.Id == id && m.State >= (int)MissionState.Completed
                       ));
        }
 public Mission[] GetActiveMissions()
 {
     using var ctx = new UchuContext();
     return(ctx.Missions.Include(m => m.Tasks).ThenInclude(m => m.Values).Where(
                m => m.Character.CharacterId == GameObject.ObjectId &&
                m.State == (int)MissionState.Active ||
                m.State == (int)MissionState.CompletedActive
                ).ToArray());
 }
示例#30
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
                );

            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);
            }
        }