Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mod: add low population gamemode switch #378

Draft
wants to merge 7 commits into
base: master
Choose a base branch
from
Draft
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
96 changes: 96 additions & 0 deletions src/Module.Server/Common/CrpgGamemodeManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
using System;
using System.Collections.Generic;
using System.Text;
using TaleWorlds.Library;
using TaleWorlds.ModuleManager;
using TaleWorlds.MountAndBlade;

namespace Crpg.Module.Common;
internal static class CrpgGamemodeManager
{
public static readonly Dictionary<string, string> Modes = new()
{
{ "cRPGBattle", "a" },
{ "cRPGTeamDeathmatch", "f" },
};

public static string InstanceByGameMode(string gameMode)
{
return Modes[gameMode];
}

public static Dictionary<string, List<string>> Maps { get; private set; } = new()
{
{ "cRPGBattle", new() },
{ "cRPGTeamDeathmatch", new() },
};

public static Dictionary<string, int> MapCounter { get; set; } = new()
{
{ "cRPGBattle", 0 },
{ "cRPGTeamDeathmatch", 0 },
};

private static readonly Random Random = new();

public static bool LoadGameConfig(string configName)
{
string newConfigFilePath = Path.Combine(Directory.GetCurrentDirectory(), ModuleHelper.GetModuleFullPath("cRPG"), InstanceByGameMode(configName) + ".txt");
try
{
string[] commands = File.ReadAllLines(newConfigFilePath);
MultiplayerOptions.Instance.InitializeFromCommandList(commands.ToList());
MultiplayerOptions.Instance.InitializeNextAndDefaultOptionContainers();
return true;
}
catch (Exception e)
{
Debug.Print($"could not read the config file {newConfigFilePath}", color: Debug.DebugColor.Red);
Debug.Print($"{e.Message}", color: Debug.DebugColor.Red);
return false;
}

}

public static void AddMaps()
{
foreach (KeyValuePair<string, string> mode in Modes)
{
string mapconfigfilepath = Path.Combine(Directory.GetCurrentDirectory(), ModuleHelper.GetModuleFullPath("cRPG"), mode.Value + "_maps.txt");
if (File.Exists(mapconfigfilepath))
{
try
{
string[] maps = File.ReadAllLines(mapconfigfilepath);

int startIndex = Random.Next(maps.Length); // Random start index between 0 and maps.Length - 1
for (int i = 0; i < maps.Length; i++)
{
int currentIndex = (startIndex + i) % maps.Length;
string map = maps[currentIndex];

if (map == string.Empty)
{
continue;
}

Maps[mode.Key].Add(map);
Debug.Print($"added {map} to {mode.Key} map pool", color: Debug.DebugColor.Red);
}
}
catch (Exception e)
{
Debug.Print($"could not read the map file {mapconfigfilepath}", color: Debug.DebugColor.Red);
Debug.Print($"{e.Message}", color: Debug.DebugColor.Red);
}
}
else
{
Debug.Print("No separate map file");
}

}

return;
}
}
47 changes: 45 additions & 2 deletions src/Module.Server/Common/CrpgServerConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ static CrpgServerConfiguration()
string? regionStr = Environment.GetEnvironmentVariable("CRPG_REGION");
Region = Enum.TryParse(regionStr, ignoreCase: true, out CrpgRegion region) ? region : CrpgRegion.Eu;
Service = Environment.GetEnvironmentVariable("CRPG_SERVICE") ?? "unknown-service";
Instance = Environment.GetEnvironmentVariable("CRPG_INSTANCE") ?? "unknown-instance";
}

public static void Init()
Expand All @@ -24,11 +23,21 @@ public static void Init()

public static CrpgRegion Region { get; }
public static string Service { get; }
public static string Instance { get; }
public static string Instance
{
get
{
return Environment.GetEnvironmentVariable("CRPG_INSTANCE") ?? "unknown-instance";
}
}

public static float TeamBalancerClanGroupSizePenalty { get; private set; } = 0f;
public static float ServerExperienceMultiplier { get; private set; } = 1.0f;
public static int RewardTick { get; private set; } = 60;
public static bool TeamBalanceOnce { get; private set; }
public static string? HighPopulationGameMode { get; private set; }
public static string? LowPopulationGameMode { get; private set; }
public static int LowPopulationGameModeMaxPlayerCount { get; private set; } = 12;
public static bool FrozenBots { get; private set; } = false;
public static Tuple<TimeSpan, TimeSpan, TimeZoneInfo>? HappyHours { get; private set; }

Expand Down Expand Up @@ -109,6 +118,40 @@ private static void SetFrozenBots(string? frozenBotsStr)
FrozenBots = frozenBots;
Debug.Print($"Set team balance once to {frozenBots}");
}

[UsedImplicitly]
[ConsoleCommandMethod("crpg_low_pop_gamemode", "Sets the gamemode for low population")]
private static void SetLowPopulationGamemode(string? lowPopGamemodeString)
{
LowPopulationGameMode = lowPopGamemodeString;
Debug.Print($"Setting low population gamemode: {LowPopulationGameMode}");
}

[UsedImplicitly]
[ConsoleCommandMethod("crpg_high_pop_gamemode", "Sets the gamemode for high population")]
private static void SetHighPopulationGamemode(string? highPopGamemodeString)
{
HighPopulationGameMode = highPopGamemodeString;
Debug.Print($"Setting high population gamemode: {HighPopulationGameMode}");
}

[UsedImplicitly]
[ConsoleCommandMethod("crpg_low_pop_gamemode_max_playercount", "Sets the maximum players for low population gamemode")]
private static void SetLowPopulationGamemodeMaxPlayerCount(string? lowPopGamemodeCountString)
{
if (lowPopGamemodeCountString == null ||
!int.TryParse(lowPopGamemodeCountString, out int lowPopMaxPlayerCount)
|| lowPopMaxPlayerCount < 0
|| lowPopMaxPlayerCount > 256)
{
Debug.Print($"Invalid playercount: {lowPopGamemodeCountString}");
return;
}

LowPopulationGameModeMaxPlayerCount = lowPopMaxPlayerCount;
Debug.Print($"Setting low population max player count: {LowPopulationGameModeMaxPlayerCount}");
}

[UsedImplicitly]
[ConsoleCommandMethod("crpg_happy_hours", "Sets the happy hours. Format: HH:MM-HH:MM,TZ")]
private static void SetHappyHours(string? happHoursStr)
Expand Down
31 changes: 29 additions & 2 deletions src/Module.Server/Common/MapPoolComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace Crpg.Module.Common;
internal class MapPoolComponent : MissionLogic
{
private static int nextMapId;

private string _nextMode = string.Empty;
private string? _forcedNextMap;

public void ForceNextMap(string map)
Expand All @@ -29,10 +29,37 @@ public void ForceNextMap(string map)

_forcedNextMap = map;
}

protected override void OnEndMission()
{
string nextMap = string.Empty;

if (CrpgServerConfiguration.LowPopulationGameMode != null && CrpgServerConfiguration.HighPopulationGameMode != null)
{
if (GameNetwork.NetworkPeerCount <= CrpgServerConfiguration.LowPopulationGameModeMaxPlayerCount)
{
_nextMode = CrpgServerConfiguration.LowPopulationGameMode;
}
else
{
_nextMode = CrpgServerConfiguration.HighPopulationGameMode;
}

if (CrpgGamemodeManager.LoadGameConfig(_nextMode))
{
CrpgGamemodeManager.MapCounter[_nextMode] = (CrpgGamemodeManager.MapCounter[_nextMode] + 1) % CrpgGamemodeManager.Maps[_nextMode].Count;
nextMap = _forcedNextMap ?? CrpgGamemodeManager.Maps[_nextMode][CrpgGamemodeManager.MapCounter[_nextMode]];

MultiplayerOptions.OptionType.Map.SetValue(nextMap, MultiplayerOptions.MultiplayerOptionsAccessMode.CurrentMapOptions);
Environment.SetEnvironmentVariable("CRPG_INSTANCE", CrpgGamemodeManager.Modes[_nextMode][0].ToString());
_forcedNextMap = null;
}

return;
}

nextMapId = (nextMapId + 1) % ListedServerCommandManager.ServerSideIntermissionManager.AutomatedMapPool.Count;
string nextMap = _forcedNextMap ?? ListedServerCommandManager.ServerSideIntermissionManager.AutomatedMapPool[nextMapId];
nextMap = _forcedNextMap ?? ListedServerCommandManager.ServerSideIntermissionManager.AutomatedMapPool[nextMapId];
MultiplayerOptions.OptionType.Map.SetValue(nextMap, MultiplayerOptions.MultiplayerOptionsAccessMode.NextMapOptions);
_forcedNextMap = null;
}
Expand Down
1 change: 1 addition & 0 deletions src/Module.Server/CrpgSubModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ public override void OnGameInitializationFinished(Game game)
base.OnGameInitializationFinished(game);
AddMaps();
Debug.Print($"Now Adding Maps", color: Debug.DebugColor.Cyan);
CrpgGamemodeManager.AddMaps();
}

private static void AddMaps()
Expand Down
1 change: 1 addition & 0 deletions src/Module.Server/MapRotation/ds_config_crpg_battle.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,4 @@ set_automated_battle_count -1
enable_automated_battle_switching
crpg_frozen_bots True
crpg_apply_harmony_patches

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
ServerName cRPG Test
ServerName cRPG Team Deathmatch
GameType cRPGTeamDeathmatch
GamePassword yoyo
AllowPollsToKickPlayers True
Expand Down Expand Up @@ -27,3 +27,4 @@ start_game
set_automated_battle_count -1
enable_automated_battle_switching
crpg_apply_harmony_patches

2 changes: 1 addition & 1 deletion src/Module.Server/Module.Server.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
<Reference Include="$(MB_SERVER_PATH)\bin\Win64_Shipping_Server\TaleWorlds.*.dll">
<Private>False</Private>
</Reference>


<Reference Include="$(MB_SERVER_PATH)\bin\Win64_Shipping_Server\Newtonsoft.Json.dll">
<Private>False</Private>
Expand Down
Loading