Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 104 additions & 0 deletions Server/HnSRandom.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
using Shared.Packet.Packets;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Server
{
public static class HnSRandom
{
public static Server server;
public static List<string> selectedPlayers = new List<string>();
/// <summary>
/// Function for private server hosts to start a random game of Hide & Seek
/// </summary>
/// <param name="arg">Integer expected for number of seekers</param>
/// <returns>Returns a string with the selected stage and seekers to display in the console</returns>
public static string StartRandomGame(string arg)
{
string stage = RandomStage();
int num = 0;
try { num = int.Parse(arg); } // checks if arg is a valid integer, if not return that the number is invalid
catch { return "Invalid number"; }
if (num > server.Clients.Count)
return "Number is higher than the amount of players";
else if (num == server.Clients.Count)
return "Please have at least one hider available";
int spacesLeft = server.Clients.Count - selectedPlayers.Count; // checks how many players have currently been unselected.
server.Logger.Warn(spacesLeft.ToString());
if (spacesLeft < num) // If spaces left is lower than the number of seekers wanted then the selectedPlayers list gets cleared
selectedPlayers.Clear();
List<string> players = new List<string>();
for (int i = 0; i < num; i++)
{
string n = RandomPlayer();
if (players.Contains(n) || selectedPlayers.Contains(n)) { i--; continue; } // if either list players or selectedPlayers contain the currently selected player, then redo the randomisation (if something happens where selectedPlayers doesnt get cleared this may cause an infinite loop)
players.Add(n);
selectedPlayers.Add(n);
}
foreach (Client client in server.Clients)
{

#pragma warning disable CS4014
client.Send(new ChangeStagePacket
{
Stage = stage,
Scenario = -1,
});
#pragma warning restore CS4014
}
string play = string.Join(',', players);
return $"Starting Random Game on {stage} with seeker(s): {play}";
}
/// <summary>
/// Selects a stage based on a list in Settings
/// </summary>
/// <returns>Returns a string of a random stage</returns>
private static string RandomStage()
{
Random r = new Random();

List<string> stageNames = new List<string>();
foreach (var stage in Settings.Instance.StageSelection)
{
if (stage.enabled == true)
stageNames.Add(stage.stageName);
}
int i = r.Next(0, stageNames.Count);
try
{
return stageNames[i];
}
catch (IndexOutOfRangeException ex)
{
server.Logger.Warn("Something has gone wrong");
return stageNames[i - 1];
}
}
/// <summary>
/// Selects a random player currently connected to the server
/// </summary>
/// <returns></returns>
private static string RandomPlayer()
{
Random r = new Random();
int i = r.Next(0, server.Clients.Count);
try
{
return server.Clients[i].Name;
}
catch
{
return server.Clients[i - 1].Name;
}
}

public static string DebugMessage()
{
string s = string.Join(',', selectedPlayers);
return $"Currently selected players: {s}";
}
}
}
9 changes: 9 additions & 0 deletions Server/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
bool restartRequested = false;
Logger consoleLogger = new Logger("Console");
DiscordBot bot = new DiscordBot();
HnSRandom.server = server;
await bot.Run();

async Task PersistShines()
Expand Down Expand Up @@ -446,6 +447,14 @@ await c.Send(new ChangeStagePacket {
return $"Sent players to {stage}:{-1}";
});

CommandHandler.RegisterCommand("randomgame", args =>
{
const string optionUsage = "Usage: randomgame <int>";
if (args.Length < 1)
{ return optionUsage; }
return HnSRandom.StartRandomGame(args[0]);
});

CommandHandler.RegisterCommand("scenario", args => {
const string optionUsage = "Valid options: merge [true/false]";
if (args.Length < 1)
Expand Down
41 changes: 39 additions & 2 deletions Server/Settings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ public static void LoadSettings() {
try {
Instance = JsonConvert.DeserializeObject<Settings>(text, new StringEnumConverter(new CamelCaseNamingStrategy())) ?? Instance;
Logger.Info("Loaded settings from settings.json");
}
if (Instance.StageSelection == null || Instance.StageSelection.Count < 1)
Instance.StageSelection = StageSelectionTable.Preset();
}
catch (Exception e) {
Logger.Warn($"Failed to load settings.json: {e}");
}
Expand All @@ -44,6 +46,7 @@ public static void SaveSettings(bool silent = false) {
public FlipTable Flip { get; set; } = new FlipTable();
public ScenarioTable Scenario { get; set; } = new ScenarioTable();
public BanListTable BanList { get; set; } = new BanListTable();
public List<StageSelectionTable> StageSelection { get; set; } = new List<StageSelectionTable>();
public DiscordTable Discord { get; set; } = new DiscordTable();
public ShineTable Shines { get; set; } = new ShineTable();
public PersistShinesTable PersistShines { get; set; } = new PersistShinesTable();
Expand All @@ -67,7 +70,41 @@ public class BanListTable {
public ISet<sbyte> GameModes { get; set; } = new SortedSet<sbyte>();
}

public class FlipTable {
public class StageSelectionTable
{
public string stageName { get; set; }
public bool enabled { get; set; } = true;
public StageSelectionTable(string name)
{
stageName = name;
}
public static List<StageSelectionTable> Preset()
{
List<StageSelectionTable> list = new List<StageSelectionTable>
{
new StageSelectionTable("CapWorldHomeStage"),
new StageSelectionTable("WaterfallWorldHomeStage"),
new StageSelectionTable("SandWorldHomeStage"),
new StageSelectionTable("LakeWorldHomeStage"),
new StageSelectionTable("ForestWorldHomeStage"),
new StageSelectionTable("CloudWorldHomeStage") { enabled = false },
new StageSelectionTable("ClashWorldHomeStage"),
new StageSelectionTable("CityWorldHomeStage"),
new StageSelectionTable("SnowWorldHomeStage"),
new StageSelectionTable("SeaWorldHomeStage"),
new StageSelectionTable("LavaWorldHomeStage"),
new StageSelectionTable("BossRaidWorldHomeStage") { enabled = false },
new StageSelectionTable("SkyWorldHomeStage"),
new StageSelectionTable("MoonWorldHomeStage"),
new StageSelectionTable("PeachWorldHomeStage"),
new StageSelectionTable("Special1WorldHomeStage") { enabled = false },
new StageSelectionTable("Special2WorldHomeStage") { enabled = false },
};
return list;
}
}

public class FlipTable {
public bool Enabled { get; set; } = true;
public ISet<Guid> Players { get; set; } = new SortedSet<Guid>();
public FlipOptions Pov { get; set; } = FlipOptions.Both;
Expand Down