public HubLevel(SkyCoreAPI plugin, string gameId, string levelPath, GameLevelInfo gameLevelInfo, bool modifiable = false) : base(plugin, "hub", gameId, levelPath, gameLevelInfo, modifiable) { AddPendingTask(() => { PlayerLocation portalInfoLocation = new PlayerLocation(256.5, 79.5, 276.5); const string hologramContent = " §d§lSkytonia§r §f§lNetwork§r" + "\n" + " §7Enter the portal and§r" + "\n" + "§7enjoy your adventure!§r" + "\n" + " §ewww.skytonia.com§r"; new Hologram(hologramContent, this, portalInfoLocation).SpawnEntity(); RunnableTask.RunTaskLater(() => { try { PlayerNPC.SpawnAllHubNPCs(this); //SpawnHubMaps(); } catch (Exception e) { BugSnagUtil.ReportBug(e, this); } }, 250); }); }
public BuildBattleGameController(SkyCoreAPI plugin) : base(plugin, "build-battle", "Build Battle", new List <string> { "build-battle-template" }) { string themeFilePath = $"{Path.GetDirectoryName(Assembly.GetEntryAssembly().Location)}\\config\\build-battle-themes.json"; //Generate Example Config if (!File.Exists(themeFilePath)) { List <BuildBattleTheme> tempThemeList = new List <BuildBattleTheme> { new BuildBattleTheme("Theme #1", new List <CachedItem> { new CachedItem(1, 1), new CachedItem(5, 0) }), new BuildBattleTheme("Theme #2", new List <CachedItem> { new CachedItem(1, 1), new CachedItem(5, 0) }) }; File.WriteAllText(themeFilePath, JsonConvert.SerializeObject(tempThemeList, Formatting.Indented)); } object jObject = JsonConvert.DeserializeObject(File.ReadAllText(themeFilePath)); if (jObject is JArray array) { try { _themeList = array.ToObject <List <BuildBattleTheme> >(); foreach (BuildBattleTheme theme in _themeList) { //Automatic Bolding if (theme.ThemeName.StartsWith("§")) { theme.ThemeName = theme.ThemeName.Substring(0, 2) + "§l" + theme.ThemeName.Substring(2, theme.ThemeName.Length - 2); } } } catch (Exception e) { BugSnagUtil.ReportBug(e, this, new AnonMetadatable((metadata) => { metadata.AddToTab("JSON", "Theme List Content", jObject); })); } } else { SkyUtil.log($"Unable to load theme list. Parsed Object was of type {(jObject == null ? "null" : $"{jObject.GetType()}")}"); } SkyUtil.log($"Initialized {_themeList.Count} Themes"); }
// public void OnEnable(PluginContext context) { context.PluginManager.LoadCommands(new SkyCommands(this)); //Initialize Generic Commands context.PluginManager.LoadCommands(Permissions); //Initialize Permission Commands context.PluginManager.LoadCommands(new GameCommands()); //Initialize GameController Commands (/gameedit) context.PluginManager.LoadCommands(new Whitelist()); //Initialize Whitelist Commands (/whitelist) //Register listeners context.Server.PlayerFactory.PlayerCreated += (sender, args) => { _shouldSchedule = false; //Avoid scheduling pending tasks once a player has joined MiNET.Player player = args.Player; player.PlayerLeave += OnPlayerLeave; if (_pendingTasks.Count > 0) { foreach (PendingTask pendingTask in _pendingTasks) { RunnableTask.RunTaskLater(() => { try { pendingTask.Invoke(); } catch (Exception e) { BugSnagUtil.ReportBug(e, new AnonMetadatable((metadata) => { metadata.AddToTab("PendingTask", "Target", pendingTask.Target); metadata.AddToTab("PendingTask", "Method", pendingTask.Method); })); } }, 5000); } _pendingTasks.Clear(); } }; //Trigger any post-launch tasks that cannot be run during startup foreach (GameController coreGameController in GameModes.Values) { coreGameController.PostLaunchTask(); } //Start RestartHandler for Automatic Reboots RestartHandler.Start(); SkyUtil.log("Initialized!"); }
public virtual void HandleHeldItemSlotChange(GameLevel gameLevel, SkyPlayer player, int newHeldItemSlot) { if (this is IMessageTickableState tickableState) { try { tickableState.SendTickableMessage(gameLevel, player, null); } catch (Exception e) { BugSnagUtil.ReportBug(e, this, gameLevel, player); } } }
public void UpdateGameState(GameState gameState) { lock (_tickLock) { try { CurrentState.LeaveState(this); } catch (Exception e) { BugSnagUtil.ReportBug(e, this, CurrentState); } CurrentState = gameState; try { CurrentState.EnterState(this); } catch (Exception e) { BugSnagUtil.ReportBug(e, this, CurrentState); //Move all players to a new game. DoForAllPlayers(player => { try { if (player == null) { return; } ExternalGameHandler.AddPlayer(player, GameType); } catch (Exception e2) { //Ignore BugSnagUtil.ReportBug(e, this, CurrentState); } }); if (gameState.GetEnumState(this) != StateType.Closing) { UpdateGameState(new VoidGameState()); } } } }
public static void RequeuePlayer(SkyPlayer player, string gameName) { if (!GameRegistrations.ContainsKey(gameName)) { player.SendMessage($"{ChatColors.Red}No game existed for the name '{gameName}'"); return; } try { GameRegistrations[gameName].AddPlayer(player); } catch (Exception e) { BugSnagUtil.ReportBug(e); } }
private void _CoreGameTick(object sender) { try { if (SkyCoreAPI.IsRebootQueued) { //Disable game-creation ticks Close(); return; } CoreGameTick(); } catch (Exception e) { BugSnagUtil.ReportBug(e, this); } }
public void ThreadPoolCallback(Object threadContext) { try { if (Cancelled) { return; } Runnable.Invoke(); CancelRunnable(RunnableId); } catch (Exception e) { BugSnagUtil.ReportBug(e); } }
public void CommandAdmin(MiNET.Player player, params string[] args) { if (!(player is SkyPlayer skyPlayer) || !skyPlayer.PlayerGroup.IsAtLeast(PlayerGroup.Admin)) { player.SendMessage("§c§l(!)§r §cYou do not have permission for this command."); return; } if (args.Length > 0) { if (args[0].Equals("players")) { player.SendMessage("§6Retrieving Game Player Counts..."); foreach (var entry in ExternalGameHandler.GameRegistrations) { int lobbyPlayers = 0; foreach (InstanceInfo instance in entry.Value.GetAllInstances()) { foreach (GameInfo gameInfo in instance.AvailableGames) { lobbyPlayers += gameInfo.CurrentPlayers; } } int gamePlayers = entry.Value.GetCurrentPlayers() - lobbyPlayers; player.SendMessage($"§e({entry.Key}) - §eLobby§6(§e{lobbyPlayers}§6) §eGame§6(§e{gamePlayers}§6)"); } return; } else if (args[0].Equals("bugtest")) { BugSnagUtil.ReportBug(new Exception("Test Exception"), player as SkyPlayer); } } player.SendMessage("§c/admin players - Lists player counts for all games"); }
public void SetPlayerTeam(SkyPlayer player, GameTeam team) { if (player == null) { throw new ArgumentException(); } try { GameTeam oldTeam = null; if (PlayerTeamDict.ContainsKey(player.Username)) { oldTeam = PlayerTeamDict[player.Username]; if (team != null) { PlayerTeamDict[player.Username] = team; } } else if (team != null) { PlayerTeamDict.Add(player.Username, team); } player.GameTeam = team; //Attach to the player //SkyUtil.log($"Updating {player.Username}'s team from {(oldTeam == null ? "null" : oldTeam.DisplayName)} to {(team == null ? "null" : team.DisplayName)}"); SetPlayerTeam(player, oldTeam, team); } catch (Exception e) { BugSnagUtil.ReportBug(e, this, player); } }
public GameLevelInfo LoadGameLevelInfo(string levelName) { try { string shortLevelName; { string[] levelNameSplit = levelName.Split('\\'); shortLevelName = levelNameSplit[levelNameSplit.Length - 1]; } string levelInfoFilename = GetGameLevelInfoLocation(RawName, shortLevelName); GameLevelInfo gameLevelInfo; if (File.Exists(levelInfoFilename)) { //SkyUtil.log($"Found '{levelInfoFilename}' for level. Loading..."); gameLevelInfo = (GameLevelInfo) JsonConvert.DeserializeObject(File.ReadAllText(levelInfoFilename), GetGameLevelInfoType(), new GameLevelInfoJsonConverter()); //Forcefully update/recalculate BlockCoordinates in-case the configuration was changed without modifying the Distance Property gameLevelInfo.LobbyMapLocation = new BlockCoordinates(gameLevelInfo.LobbyMapLocation.X, gameLevelInfo.LobbyMapLocation.Y, gameLevelInfo.LobbyMapLocation.Z); //Ensure all values are non-null bool dirty = false; if (string.IsNullOrEmpty(gameLevelInfo.GameType)) { gameLevelInfo.GameType = RawName; dirty = true; } if (string.IsNullOrEmpty(gameLevelInfo.LevelName)) { gameLevelInfo.LevelName = shortLevelName; dirty = true; } if (dirty) { File.WriteAllText(levelInfoFilename, JsonConvert.SerializeObject(gameLevelInfo, Formatting.Indented)); //SkyUtil.log($"Updating '{levelInfoFilename}' for level. Saving..."); } } else { //SkyUtil.log($"Could not find '{levelInfoFilename} for level. Generating from base."); gameLevelInfo = new GameLevelInfo(RawName, levelName, 6000, new PlayerLocation(255.5, 15, 268.5, 180, 180)); File.WriteAllText(levelInfoFilename, JsonConvert.SerializeObject(gameLevelInfo, Formatting.Indented)); //SkyUtil.log($"Updating '{levelInfoFilename}' for level. Saving..."); } return gameLevelInfo; } catch (Exception e) { BugSnagUtil.ReportBug(e, this); return null; } }
public void Configure(MiNetServer server) { Server = server; SkyUtil.log("Hooking into MiNET."); Instance = this; SkyUtil.log("SkyCore Initializing..."); //Initialize Bugsnag Exception Reporting BugSnagUtil.Init(); SkyUtil.log($"Dev Mode: ({Config.GetProperty("dev-server", "false")})"); try { if (Config.GetProperty("dev-server", "false").Equals("true")) { IsDevelopmentServer = true; SkyUtil.log("Initializing Server In Development Mode"); //Forcefully Enable Whitelist Whitelist.LoadWhitelist(); if (!Whitelist.WhitelistContent.Enabled) { SkyUtil.log("Enforcing Whitelist"); Whitelist.WhitelistContent.Enabled = true; Whitelist.SaveWhitelist(); } } } catch (Exception e) { BugSnagUtil.ReportBug(e); } ServerPath = Environment.CurrentDirectory; SkyUtil.log($"Registered Server Path at '{ServerPath}'"); CurrentIp = new WebClient().DownloadString("http://icanhazip.com").Replace("\n", "") + ":" + Config.GetProperty("port", "19132"); SkyUtil.log($"Registered current IP as {CurrentIp}"); ExternalGameHandler.CurrentHostAddress = CurrentIp; BlockFactory.CustomBlockFactory = new SkyBlockFactory(); server.LevelManager = new SkyLevelManager(this); //Create Games once the LevelManager has been initialized to avoid launching without any levels ExternalGameHandler.Init(server); //Start listening for game servers string serverGame = Config.GetProperty("game-type", "none"); SkyUtil.log($"Setting up Custom Game {serverGame}..."); GameType = serverGame; try { Type gameControllerType = null; string gameName = null; switch (serverGame) { case "murder": { gameName = "Murder Mystery"; gameControllerType = typeof(MurderGameController); break; } case "build-battle": { gameName = "Build Battle"; gameControllerType = typeof(BuildBattleGameController); break; } case "none": { gameName = "Pure Hub"; //none -> hub GameType = "hub"; gameControllerType = typeof(HubController); break; } } if (gameControllerType == null) { SkyUtil.log("No Game Loaded."); return; } SkyUtil.log($"Initializing Game {gameName}..."); _initializeCustomGame(Activator.CreateInstance(gameControllerType, this) as GameController); Thread.Sleep(1000); //Pause the main thread for a second to ensure the levels are setup and avoid any CME SkyUtil.log($"Finished Initializing {gameName}"); //Register all remaining games bool spawnNPC = gameName.Equals("Pure Hub"); ExternalGameHandler.RegisterGameIntent("murder", spawnNPC); ExternalGameHandler.RegisterGameIntent("build-battle", spawnNPC); ExternalGameHandler.RegisterGameIntent("block-hunt", spawnNPC); ExternalGameHandler.RegisterGameIntent("bed-wars", spawnNPC); } catch (Exception e) { BugSnagUtil.ReportBug(e); //TODO: Prevent players joining } // Permissions = new SkyPermissions(this); server.PlayerFactory = new SkyPlayerFactory { SkyCoreApi = this }; SkyUtil.log("Finished Hooks."); }
public override void EnterState(GameLevel gameLevel) { base.EnterState(gameLevel); GunPartLocations.Clear(); PlayerSpawnLocations.Clear(); GunPartLocations.AddRange(((MurderLevelInfo)((MurderLevel)gameLevel).GameLevelInfo).GunPartLocations); PlayerSpawnLocations.AddRange(((MurderLevelInfo)((MurderLevel)gameLevel).GameLevelInfo).PlayerSpawnLocations); while (PlayerSpawnLocations.Count < gameLevel.GetMaxPlayers()) { PlayerSpawnLocations.Add(((MurderLevelInfo)((MurderLevel)gameLevel).GameLevelInfo).PlayerSpawnLocations[0]); } EndTick = gameLevel.Tick + MaxGameTime + PreStartTime; try { RunnableTask.RunTask(() => { //Create new collection due to iterating over a live list ICollection <SkyPlayer> players = gameLevel.GetAllPlayers(); foreach (SkyPlayer player in players) { player.SetEffect(new Blindness { Duration = 80, Particles = false }); //Should be 3 seconds? player.SetHideNameTag(true); player.IsAlwaysShowName = false; player.SetNameTagVisibility(false); } List <PlayerLocation> usedSpawnLocations = new List <PlayerLocation>(); gameLevel.DoForAllPlayers(player => { //Pre-add all players to the map to avoid any unnecessary contains if (PlayerAmmoCounts.ContainsKey(player.Username)) { PlayerAmmoCounts[player.Username] = 0; } else { PlayerAmmoCounts.Add(player.Username, 0); } if (PlayerGunPartCounts.ContainsKey(player.Username)) { PlayerGunPartCounts[player.Username] = 0; } else { PlayerGunPartCounts.Add(player.Username, 0); } player.SetGameMode(GameMode.Adventure); //Avoid spawning two players in the same location PlayerLocation spawnLocation; while (usedSpawnLocations.Contains((spawnLocation = PlayerSpawnLocations[Random.Next(PlayerSpawnLocations.Count)]))) { // } usedSpawnLocations.Add(spawnLocation); //Mark spawn position for AFK Check player.SpawnPosition = spawnLocation; player.Teleport(spawnLocation); player.SetHideNameTag(true); player.IsAlwaysShowName = false; player.SetNameTagVisibility(false); player.Freeze(true); player.HungerManager.Hunger = 6; //Set food to 'unable to run' level. player.SendUpdateAttributes(); //TODO: Not required? Or is this required for Hunger }); List <MurderTeam> teamRotation = new List <MurderTeam> { MurderTeam.Murderer, MurderTeam.Detective, MurderTeam.Innocent }; int offset = Random.Next(teamRotation.Count); for (int i = 0; i < 12; i++) { MurderTeam team = teamRotation[(offset + i) % 3]; foreach (SkyPlayer player in players) { TitleUtil.SendCenteredSubtitle(player, team.TeamPrefix + "§l" + team.TeamName); //Poorly enforce speed if (i == 0 || i == 11) { player.Freeze(true); player.SetHideNameTag(true); player.IsAlwaysShowName = false; player.SetNameTagVisibility(false); } } //SkyUtil.log($"Printed scroll {i}/12, with {team.TeamPrefix + "§l" + team.TeamName}"); Thread.Sleep(250); } int murdererIdx = Random.Next(players.Count), detectiveIdx = 0; int idx = 0; while (++idx < 50 && (detectiveIdx = Random.Next(players.Count)) == murdererIdx) { // } //Console.WriteLine($"Rolled Murderer as {murdererIdx} Detective as {detectiveIdx} with 0-{players.Count - 1} possible indexes"); idx = 0; foreach (SkyPlayer player in players) { if (idx == murdererIdx) { gameLevel.SetPlayerTeam(player, MurderTeam.Murderer); } else if (idx == detectiveIdx) { gameLevel.SetPlayerTeam(player, MurderTeam.Detective); } else { gameLevel.SetPlayerTeam(player, MurderTeam.Innocent); } idx++; } //Workaround for one player (single murderer) if (((MurderLevel)gameLevel).Detective == null) { ((MurderLevel)gameLevel).Detective = ((MurderLevel)gameLevel).Murderer; } gameLevel.DoForPlayersIn(player => { TitleUtil.SendCenteredSubtitle(player, "§a§lInnocent §r\n§7Track down the murderer!"); }, MurderTeam.Innocent); gameLevel.DoForPlayersIn(player => { TitleUtil.SendCenteredSubtitle(player, "§9§lDetective §r\n§7Track down the murderer!"); player.Inventory.SetInventorySlot(0, new ItemInnocentGun()); //SkyUtil.log($"In Slot 0 = {player.Inventory.GetSlots()[0].GetType().FullName}"); player.Inventory.SetInventorySlot(9, new ItemArrow()); PlayerAmmoCounts[player.Username] = int.MaxValue; }, MurderTeam.Detective); gameLevel.DoForPlayersIn(InitializeMurderer, MurderTeam.Murderer); gameLevel.DoForAllPlayers(player => { player.SendAdventureSettings(); player.Freeze(false); //Ensure this player is at the correct spawn location if (gameLevel.GetBlock(player.KnownPosition).Id != 0) { PlayerLocation newLocation = (PlayerLocation)player.KnownPosition.Clone(); newLocation.Y++; player.Teleport(newLocation); } }); }); } catch (Exception e) { BugSnagUtil.ReportBug(e, this, gameLevel); } }
//New GameLevel Method public void AddPlayer(SkyPlayer player) { if (player.Level != this && player.Level is GameLevel level) { level.RemovePlayer(player, true); //Clear from old world } //Remove a player from _incomingPlayers only if it's non-empty. //Avoid claiming a lock for a useless check if (_incomingPlayers.Count > 0) { lock (_incomingPlayers) { if (_incomingPlayers.ContainsKey(player.Username)) { _incomingPlayers.Remove(player.Username); } } } GameTeam defaultTeam = GetDefaultTeam(); SetPlayerTeam(player, defaultTeam); //SkyUtil.log($"Added {player.Username} to team {defaultTeam.DisplayName} in game {GameId}"); /*if (player.Level != this) * { * //Only show the level transition screen to players changing games on this instance * //player.SpawnLevel(this, GameLevelInfo.LobbyLocation, !_incomingPlayers.ContainsKey(player.Username)); * player.SpawnLevel(this, GameLevelInfo.LobbyLocation, false); //Remove loading screen to prevent 'building terrain' issue * } * else //Still teleport the player to the spawn location * { * player.Teleport(GameLevelInfo.LobbyLocation); * }*/ //Fix for maps on first join to an instance player.SpawnLevel(this, GameLevelInfo.LobbyLocation, false); //Remove loading screen to prevent 'building terrain' issue try { CurrentState.InitializePlayer(this, player); } catch (Exception e) { BugSnagUtil.ReportBug(e, this, CurrentState, player); } //Update Time McpeSetTime message = McpeSetTime.CreateObject(); message.time = GameLevelInfo.WorldTime; player.SendPackage(message); // //Pending Tasks //Attempts to execute tasks like spawning NPCs in once a single player has loaded the world if (_shouldSchedule) { _shouldSchedule = false; if (_pendingTasks.Count > 0) { foreach (SkyCoreAPI.PendingTask pendingTask in _pendingTasks) { RunnableTask.RunTaskLater(() => { try { pendingTask.Invoke(); } catch (Exception e) { BugSnagUtil.ReportBug(e, new AnonMetadatable((metadata) => { metadata.AddToTab("PendingTask", "Target", pendingTask.Target); metadata.AddToTab("PendingTask", "Method", pendingTask.Method); })); } }, 250); //Small delay for the level to initialize } _pendingTasks.Clear(); } } }
/** * Credit to @gurun, as what is below is based on his work. */ public static List <Entity> SpawnMapImage(string imageLocation, int width, int height, Level level, BlockCoordinates spawnLocation, MapDirection mapDirection = MapDirection.South) { var spawnedEntities = new List <Entity>(); try { Bitmap image; CachedMap cachedMap; if (CachedMaps.ContainsKey(imageLocation)) { cachedMap = CachedMaps[imageLocation]; image = cachedMap.CachedImage; //Dodgily ensure the building flag is disabled cachedMap.IsBuilding = false; //SkyUtil.log($"Using Cached Image for {imageLocation}"); } else { if (!File.Exists(imageLocation)) { SkyUtil.log($"File doesn't exist for Map ({imageLocation})"); return(spawnedEntities); } image = new Bitmap((Bitmap)Image.FromFile(imageLocation), width * 128, height * 128); cachedMap = new CachedMap(image); //SkyUtil.log($"Loading Image for {imageLocation}"); } BlockCoordinates center = spawnLocation; for (int x = 0; x < width; x++) { int xSpawnLoc = center.X + x; for (int y = 0; y < height; y++) { byte[] bitmapToBytes; if (cachedMap.IsBuilding) { var croppedImage = CropImage(image, new Rectangle(new Point(x * 128, y * 128), new Size(128, 128))); bitmapToBytes = BitmapToBytes(croppedImage, true); if (bitmapToBytes.Length != 128 * 128 * 4) { return(spawnedEntities); //TODO: Throw Exception/Alert Log? } cachedMap.CachedBitmaps.Add(new Tuple <int, int>(x, y), bitmapToBytes); } else { bitmapToBytes = cachedMap.CachedBitmaps[new Tuple <int, int>(x, y)]; } MapEntity frame = new MapEntity(level); frame.ImageProvider = new MapImageProvider { Batch = CreateCachedPacket(frame.EntityId, bitmapToBytes) }; frame.SpawnEntity(); AddMapIdToDictionary(level is GameLevel gameLevel ? gameLevel.GameId : level.LevelId, frame.EntityId); BlockCoordinates frambc = new BlockCoordinates(xSpawnLoc, center.Y + height - y - 2, center.Z); ItemFrameBlockEntity itemFrameBlockEntity = new ItemFrameBlockEntity { Coordinates = frambc }; var itemFrame = new FullyLuminousItemFrame(frame, itemFrameBlockEntity, level) { Coordinates = frambc, Metadata = (byte)mapDirection, }; level.SetBlock(itemFrame, true, false); level.SetBlockEntity(itemFrameBlockEntity); spawnedEntities.Add(frame); } } if (cachedMap.IsBuilding) { CachedMaps.TryAdd(imageLocation, cachedMap); cachedMap.IsBuilding = false; //Completely Cached } } catch (Exception e) { SkyUtil.log("Aborted image generation"); BugSnagUtil.ReportBug(e); } return(spawnedEntities); }
public static void ShowGameList(SkyPlayer player) { try { if (player == null || !player.IsConnected || player.KnownPosition == null) { SkyUtil.log("Attempted to show GameList to a null player"); return; } var simpleForm = new SimpleForm { Title = "§lSkytonia Network", Content = "", Buttons = new List <Button> { new Button { Text = $"§3§lNetwork Lobby\n{GetFormattedPlayerCount("hub")}", Image = new Image { Type = "url", Url = "https://static.skytonia.com/dl/hubiconmenu.png" }, ExecuteAction = delegate { ExternalGameHandler.AddPlayer(player, "hub"); } }, new Button { Text = $"§c§lMurder Mystery\n{GetFormattedPlayerCount("murder")}", Image = new Image { Type = "url", Url = "https://static.skytonia.com/dl/murdericonmenu.png" }, ExecuteAction = delegate { ExternalGameHandler.AddPlayer(player, "murder"); } }, new Button { Text = $"§6§l Build Battle\n{GetFormattedPlayerCount("build-battle")}", Image = new Image { Type = "url", Url = "https://static.skytonia.com/dl/buildbattleiconmenu.png" }, ExecuteAction = delegate { ExternalGameHandler.AddPlayer(player, "build-battle"); } }, new Button { Text = $"§d§lComing Soon...", Image = new Image { Type = "url", Url = "https://static.skytonia.com/dl/comingsooniconmenu.png" }, ExecuteAction = delegate { } //Empty } } }; player.SendForm(simpleForm); } catch (Exception e) { BugSnagUtil.ReportBug(e); } }
public override void OnTick(GameLevel gameLevel, int currentTick, out int outTick) { outTick = currentTick; //Update BarHandlers for all online players every 500 milliseconds (1 tick) gameLevel.DoForAllPlayers(player => player.BarHandler?.DoTick()); //DISABLE PARTICLES UNTIL THE 0,0 BUG IS FIXED /*if (currentTick % 2 == 0) * { * //Do Hub Particles * for (int i = 0; i < ParticleEventCount; i++) * { * Vector3 particleLocation = HubCentreLocation.ToVector3(); * * particleLocation.X += (Random.Next(2) == 0 ? -1 : 1) * (float)(Random.NextDouble() * 25); * particleLocation.Y += (Random.Next(2) == 0 ? -1 : 1) * (float)(Random.NextDouble() * 15); * particleLocation.Z += (Random.Next(2) == 0 ? -1 : 1) * (float)(Random.NextDouble() * 25); * * McpeLevelEvent particleEvent = McpeLevelEvent.CreateObject(); * particleEvent.eventId = 0x4000 | (int) ParticleType.WitchSpell; * particleEvent.position = particleLocation; * particleEvent.data = 13369599; * gameLevel.RelayBroadcast(particleEvent); * } * }*/ if (currentTick % 2 == 0) { foreach (SkyPlayer player in gameLevel.Players.Values) { //Player is not initialized yet. if (player == null || !player.IsConnected || player.KnownPosition == null) { continue; } if (IsInPortal(player.KnownPosition)) { PlayerLocation teleportLocation = player.KnownPosition; teleportLocation.Z -= 2; player.Teleport(teleportLocation); try { GameUtil.ShowGameList(player); } catch (Exception e) { BugSnagUtil.ReportBug(e, this, player); } } else if (IsInInvisRegion(player.KnownPosition)) { if (player.IsGameSpectator) { continue; } //SkyUtil.log($"Isnt Game Spectator in team {player.GameTeam.DisplayName}. Setting to Spectator"); gameLevel.SetPlayerTeam(player, HubTeam.Spectator); } else if (player.IsGameSpectator) { //SkyUtil.log($"Is Game Spectator in team {player.GameTeam.DisplayName}. Setting to Player"); gameLevel.SetPlayerTeam(player, HubTeam.Player); } } } }
public override void OnTick(GameLevel gameLevel, int currentTick, out int outTick) { int currentPlayers = gameLevel.GetGamePlayerCount(), //Doesn't count incoming players requiredPlayers = GetRequiredPlayers(gameLevel); string actionBarMessage = null; if (currentPlayers < requiredPlayers) { _startCountdownTick = -1; //Reset the timer //Only update action bar every second if (currentTick % 2 == 0) { actionBarMessage = $"§d§lStarting Soon:§r §7({gameLevel.GetPlayerCount()}/{GetRequiredPlayers(gameLevel)}) §fPlayers Required..."; } } else { if (_startCountdownTick == -1) { _startCountdownTick = currentTick; } //Only update action bar every second if (currentTick % 2 == 0) { int secondsRemaining = (GetCountdownTicks() - (currentTick - _startCountdownTick)) / 2; if (secondsRemaining <= 0) { if (secondsRemaining == 0) { actionBarMessage = "§d§lGame Starting:§r §fBeginning Now..."; gameLevel.UpdateGameState(GetNextGameState(gameLevel)); } } else { actionBarMessage = $"§d§lGame Starting:§r §7{secondsRemaining} §fSecond{(secondsRemaining == 1 ? "" : "s")} Remaining..."; } } } if (actionBarMessage != null) { foreach (SkyPlayer player in gameLevel.GetPlayers()) { player.BarHandler.AddMajorLine(actionBarMessage, 2); } } /* * Portal Handler */ if (currentTick % 2 == 0) { foreach (var player in gameLevel.Players.Values) { //Player is not initialized yet. if (player == null || !player.IsConnected || player.KnownPosition == null) { continue; } if (IsInPortal(player.KnownPosition)) { PlayerLocation teleportLocation = player.KnownPosition; teleportLocation.Z -= 2; player.Teleport(teleportLocation); try { GameUtil.ShowGameList(player as SkyPlayer); } catch (Exception e) { BugSnagUtil.ReportBug(e, this, player as SkyPlayer); } } } } outTick = currentTick; }
public override void Close() { try { GameLevelTick.Dispose(); } catch (Exception e) { BugSnagUtil.ReportBug(e, this); } try { GameLevelTickThread.Abort(); } catch (Exception e) { BugSnagUtil.ReportBug(e, this); } try { DoForAllPlayers(player => { ExternalGameHandler.AddPlayer(player, "hub"); }); } catch (Exception e) { BugSnagUtil.ReportBug(e, this); } try { if (CurrentState.GetEnumState(this) != StateType.Closing) { UpdateGameState(new VoidGameState()); } } catch (Exception e) { BugSnagUtil.ReportBug(e, this); } try { base.Close(); } catch (Exception e) { BugSnagUtil.ReportBug(e, this); } try { Plugin.Server.LevelManager.Levels.Remove(this); } catch (Exception e) { BugSnagUtil.ReportBug(e, this); } }
// public static void RegisterGameIntent(string gameName, bool spawnNPC = false) { bool npcOnly = false; //Some games may not be completed. Use an NPC as a placeholder if (spawnNPC) { string neatName = gameName; PlayerLocation npcLocation = new PlayerLocation(0.5D, 30D, 16.5D, 180F, 180F, 0F); switch (gameName) { case "murder": { neatName = "§c§lMurder Mystery"; npcLocation = new PlayerLocation(260.5, 77, 271.5, 180F, 180F, 0F); break; } case "build-battle": { neatName = "§e§lBuild Battle"; npcLocation = new PlayerLocation(252.5, 77, 271.5, 180F, 180F, 0F); break; } case "block-hunt": { neatName = PlayerNPC.ComingSoonName; npcLocation = new PlayerLocation(263.5, 77, 269.5, 180F, 180F, 0F); npcOnly = true; break; } case "bed-wars": { neatName = PlayerNPC.ComingSoonName; npcLocation = new PlayerLocation(249.5, 77, 269.5, 180F, 180F, 0F); npcOnly = true; break; } } if (!gameName.Equals("hub")) { try { PlayerNPC.SpawnHubNPC(null, neatName, npcLocation, $"GID:{gameName}"); } catch (Exception e) { Console.WriteLine(e); } } } { if (!GameRegistrations.ContainsKey(gameName)) { //Initialize GamePool GamePool gamePool = GetGamePool(gameName); if (npcOnly) { gamePool.Active = false; return; } } else { return; //Already listening, Don't start again. } } ISubscriber subscriber = RedisPool.GetSubscriber(); /* * Channel <game>_info * Format: * {ip-address}:{port}:{current-players}:{available-servers} */ subscriber.SubscribeAsync($"{GetDevelopmentPrefix()}{gameName}_info", (channel, message) => { try { string[] messageSplit = ((string)message).Split(':'); string hostAddress = messageSplit[0]; if (!ushort.TryParse(messageSplit[1], out ushort hostPort)) { SkyUtil.log($"Invalid format of port in message {message}"); return; } InstanceInfo instanceInfo; if (!GameRegistrations.TryGetValue(gameName, out var gamePool)) { string gameHostAddress = (hostAddress + ":" + hostPort).Equals(SkyCoreAPI.Instance.CurrentIp) ? "local" : hostAddress; instanceInfo = new InstanceInfo { HostAddress = gameHostAddress, HostPort = hostPort }; SkyUtil.log($"Game {gameName} missing from GameRegistrations! Re-Registering..."); RegisterGame(gameName, instanceInfo); } else { instanceInfo = (hostAddress + ":" + hostPort).Equals(SkyCoreAPI.Instance.CurrentIp) ? gamePool.GetLocalInstance() : gamePool.GetInstance(hostAddress + ":" + hostPort); } int.TryParse(messageSplit[2], out var instancePlayers); instanceInfo.CurrentPlayers = instancePlayers; instanceInfo.AvailableGames = PopulateGameList(messageSplit[3].Split('|'), new List <GameInfo>()); instanceInfo.Update(); //SkyUtil.log($"Updated {availableGames.Count} available games on {gameName} ({hostAddress + ":" + hostPort})"); } catch (Exception e) { BugSnagUtil.ReportBug(e); } }); }
protected void PreGameTick(object sender) { try { int tick = Tick; lock (_tickLock) { GameTick(++tick); CurrentState.OnTick(this, tick, out tick); } //Process player action/popup bars foreach (MiNET.Player player in Players.Values) { //Attempt to clean up any players who are no longer in this game. if (player == null || !player.IsConnected || player.Level != this) { player?.DespawnEntity(); RemovePlayer(player); continue; } try { if (player is SkyPlayer skyPlayer) { skyPlayer.BarHandler.DoTick(); } } catch (Exception e) { // } } /* * Clean up any 'incoming players' who never showed up * '15 seconds' to appear before they are cleared */ lock (_incomingPlayers) { if (_incomingPlayers.Count > 0) { long currentTime = DateTimeOffset.Now.ToUnixTimeSeconds(); List <string> toRemovePlayers = new List <string>(); foreach (KeyValuePair <string, long> entry in _incomingPlayers) { //entry.Value starts off as 15 seconds ahead of UNIX time if (entry.Value - currentTime < 0) { toRemovePlayers.Add(entry.Key); } } foreach (string toRemove in toRemovePlayers) { _incomingPlayers.Remove(toRemove); } } } Tick = tick; //Workaround? } catch (Exception e) { BugSnagUtil.ReportBug(e, this, CurrentState); } }
public static PlayerPunishments GetPunishmentsFor(string xuid) { if (PlayerPunishmentCache.ContainsKey(xuid)) { return(PlayerPunishmentCache[xuid]); } PlayerPunishments playerPunishments = null; new DatabaseAction().Query( "SELECT `punish_type`, `issuer`, `reason`, `active`, `duration_amount`, `duration_unit`, `issue_time` FROM `punishments` WHERE `player_xuid`=@xuid;", (command) => { command.Parameters.AddWithValue("@xuid", xuid); }, (reader) => { if (reader.HasRows) { Dictionary <PunishmentType, SortedSet <Punishment> > punishmentMap = new Dictionary <PunishmentType, SortedSet <Punishment> >(); while (reader.HasRows) { do { try { Enum.TryParse(reader.GetString(0), out PunishmentType punishmentType); SortedSet <Punishment> punishments; if (punishmentMap.ContainsKey(punishmentType)) { punishments = punishmentMap[punishmentType]; } else { punishments = new SortedSet <Punishment>(); punishmentMap.Add(punishmentType, punishments); } int durationAmount = reader.GetInt16(4); Enum.TryParse(reader.GetString(5), out DurationUnit durationUnit); punishments.Add(new Punishment(reader.GetString(2), reader.GetString(1), reader.GetBoolean(3), durationAmount, durationUnit, GetExpiryFromIssueDate(reader.GetDateTime(6), durationAmount, durationUnit))); } catch (Exception e) { SkyUtil.log($"Failed to read punishment row for xuid='{xuid}'"); BugSnagUtil.ReportBug(e); } } while (reader.Read()); reader.NextResult(); } if (punishmentMap.Count > 0) { playerPunishments = new PlayerPunishments(punishmentMap); } } }, null); if (playerPunishments == null) { //SkyUtil.log($"No punishments for '{xuid}'. Providing fresh object."); playerPunishments = new PlayerPunishments(); } PlayerPunishmentCache.TryAdd(xuid, playerPunishments); return(playerPunishments); }
public static void TriggerReboot(bool force = false) { if (Timer != null) { Timer.Dispose(); Timer = null; } else { SkyUtil.log("Attempted to double-trigger a reboot! Ignoring..."); return; //If Timer == null, there should already be a reboot happening. } SkyUtil.log("Shutting down using Restart Handler"); SkyUtil.log("Moving all players to first available hub"); //Remove this instance from the game pool string gameType = SkyCoreAPI.Instance.GameType; if (ExternalGameHandler.GameRegistrations.TryGetValue(gameType, out GamePool gamePool)) { List <InstanceInfo> toRemoveInstances = new List <InstanceInfo>(); foreach (InstanceInfo instanceInfo in gamePool.GetAllInstances()) { if (instanceInfo.HostAddress.Equals("local")) { toRemoveInstances.Add(instanceInfo); } } foreach (InstanceInfo toRemoveInstance in toRemoveInstances) { gamePool.RemoveInstance(toRemoveInstance); } } //Remove ourselves from the list, and force players to a new hub if (gamePool != null && gameType.Equals("hub")) { if (gamePool.GetAllInstances().Count > 0) { foreach (SkyPlayer player in SkyCoreAPI.Instance.GetAllOnlinePlayers()) { ExternalGameHandler.AddPlayer(player, "hub"); } //Wait for players to leave Thread.Sleep(5000); } //else - No hub servers to send players to. Forfeit all players. } else { SkyCoreAPI.IsRebootQueued = true; //Force will ignore this and kick all players immediately if (!force && SkyCoreAPI.Instance.GameModes.TryGetValue(gameType, out GameController localGameController) && !localGameController.GameLevels.IsEmpty) { ICollection <GameLevel> gameLevels = localGameController.GameLevels.Values; long expiryForceTime = DateTimeOffset.Now.ToUnixTimeSeconds() + 300; //5 minute timeout if the game is still running int totalPlayers; do { totalPlayers = 0; foreach (GameLevel gameLevel in gameLevels) { if (gameLevel.CurrentState.GetEnumState(gameLevel).IsJoinable()) { //We're allowed to kick all players foreach (SkyPlayer player in gameLevel.GetAllPlayers()) { ExternalGameHandler.AddPlayer(player, "hub"); } } else { totalPlayers += gameLevel.GetAllPlayers().Count; } } if (totalPlayers > 0) { SkyUtil.log( $"Waiting for {totalPlayers} to finish games before closing this instance {expiryForceTime - DateTimeOffset.Now.ToUnixTimeSeconds()} seconds remaining."); Thread.Sleep(15000); //Check every 1 second if the game has finished } } while (totalPlayers > 0 && DateTimeOffset.Now.ToUnixTimeSeconds() < expiryForceTime); } } SkyUtil.log("Shutting down..."); //Start Actual Shutdown MiNetServer server = SkyCoreAPI.Instance.Server; try { if (server.PluginManager.Plugins.Count > 1) { foreach (object pluginObject in server.PluginManager.Plugins) { if (pluginObject is IPlugin plugin) { plugin.OnDisable(); } } server.PluginManager.Plugins.Clear(); } else { SkyCoreAPI.Instance.OnDisable(); } } catch (Exception e) { BugSnagUtil.ReportBug(e); } try { server.StopServer(); } catch (Exception e) { BugSnagUtil.ReportBug(e); } Environment.Exit(0); }