Skip to content
This repository was archived by the owner on Apr 15, 2026. It is now read-only.

Commit c2861bc

Browse files
author
Dankrushen
authored
Merge pull request #223 from Grover-c13/3.2.5
MultiAdmin 3.2.5
2 parents 999c6d7 + 96cc592 commit c2861bc

9 files changed

Lines changed: 85 additions & 31 deletions

File tree

MultiAdmin/Config/MultiAdminConfig.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ public class MultiAdminConfig : InheritableConfigRegister
1818
new ConfigEntry<string>("config_location", "", false,
1919
"Config Location", "The default location for the game to use for storing configuration files (a directory)");
2020

21+
public ConfigEntry<string> AppDataLocation { get; } =
22+
new ConfigEntry<string>("appdata_location", "",
23+
"AppData Location", "The location for the game to use for AppData (a directory)");
24+
2125
public ConfigEntry<bool> DisableConfigValidation { get; } =
2226
new ConfigEntry<bool>("disable_config_validation", false,
2327
"Disable Config Validation", "Disable the config validator");

MultiAdmin/EventInterfaces.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,47 +4,47 @@ public interface IMAEvent
44
{
55
}
66

7-
public interface IEventServerPreStart: IMAEvent
7+
public interface IEventServerPreStart : IMAEvent
88
{
99
void OnServerPreStart();
1010
}
1111

12-
public interface IEventServerStart: IMAEvent
12+
public interface IEventServerStart : IMAEvent
1313
{
1414
void OnServerStart();
1515
}
1616

17-
public interface IEventServerStop: IMAEvent
17+
public interface IEventServerStop : IMAEvent
1818
{
1919
void OnServerStop();
2020
}
2121

22-
public interface IEventRoundEnd: IMAEvent
22+
public interface IEventRoundEnd : IMAEvent
2323
{
2424
void OnRoundEnd();
2525
}
2626

27-
public interface IEventWaitingForPlayers: IMAEvent
27+
public interface IEventWaitingForPlayers : IMAEvent
2828
{
2929
void OnWaitingForPlayers();
3030
}
3131

32-
public interface IEventRoundStart: IMAEvent
32+
public interface IEventRoundStart : IMAEvent
3333
{
3434
void OnRoundStart();
3535
}
3636

37-
public interface IEventCrash: IMAEvent
37+
public interface IEventCrash : IMAEvent
3838
{
3939
void OnCrash();
4040
}
4141

42-
public interface IEventTick: IMAEvent
42+
public interface IEventTick : IMAEvent
4343
{
4444
void OnTick();
4545
}
4646

47-
public interface IServerMod: IMAEvent
47+
public interface IServerMod : IMAEvent
4848
{
4949
}
5050

MultiAdmin/Exceptions.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@ namespace MultiAdmin
44
{
55
public static class Exceptions
66
{
7+
[Serializable]
78
public class ServerNotRunningException : Exception
89
{
910
public ServerNotRunningException() : base("The server is not running")
1011
{
1112
}
1213
}
1314

15+
[Serializable]
1416
public class ServerAlreadyRunningException : Exception
1517
{
1618
public ServerAlreadyRunningException() : base("The server is already running")

MultiAdmin/Features/RestartRoundCounter.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
using System;
21
using MultiAdmin.Features.Attributes;
32

43
namespace MultiAdmin.Features

MultiAdmin/Program.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ namespace MultiAdmin
1515
{
1616
public static class Program
1717
{
18-
public const string MaVersion = "3.2.4.3";
18+
public const string MaVersion = "3.2.5.1";
1919
public const string RecommendedMonoVersion = "5.18";
2020

2121
private static readonly List<Server> InstantiatedServers = new List<Server>();

MultiAdmin/Server.cs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,9 +175,11 @@ private set
175175

176176
private void MainLoop()
177177
{
178+
Stopwatch timer = new Stopwatch();
178179
while (IsGameProcessRunning)
179180
{
180-
Stopwatch timer = Stopwatch.StartNew();
181+
timer.Reset();
182+
timer.Start();
181183

182184
foreach (IEventTick tickEvent in tick) tickEvent.OnTick();
183185

@@ -345,13 +347,19 @@ public void StartServer(bool restartOnCrash = true)
345347
scpslArgs.Add($"-configpath \"{configLocation}\"");
346348
}
347349

350+
string appDataPath = Utils.GetFullPathSafe(ServerConfig.AppDataLocation.Value);
351+
if (!string.IsNullOrEmpty(appDataPath))
352+
{
353+
scpslArgs.Add($"-appdatapath \"{appDataPath}\"");
354+
}
355+
348356
scpslArgs.RemoveAll(string.IsNullOrEmpty);
349357

350358
string argsString = string.Join(" ", scpslArgs);
351359

352360
Write($"Starting server with the following parameters:\n{scpslExe} {argsString}");
353361

354-
ProcessStartInfo startInfo = new ProcessStartInfo(scpslExe, argsString);
362+
ProcessStartInfo startInfo = new ProcessStartInfo(scpslExe, argsString) {CreateNoWindow = true};
355363

356364
ForEachHandler<IEventServerPreStart>(eventPreStart => eventPreStart.OnServerPreStart());
357365

MultiAdmin/ServerIO/StringSections.cs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System;
12
using System.Collections.Generic;
23
using System.Text;
34
using MultiAdmin.ConsoleTools;
@@ -45,6 +46,12 @@ public StringSections(StringSection[] sections)
4546

4647
public static StringSections FromString(string fullString, int sectionLength, ColoredMessage leftIndicator = null, ColoredMessage rightIndicator = null, ColoredMessage sectionBase = null)
4748
{
49+
int rightIndicatorLength = rightIndicator?.Length ?? 0;
50+
int totalIndicatorLength = (leftIndicator?.Length ?? 0) + rightIndicatorLength;
51+
52+
if (fullString.Length > sectionLength && sectionLength <= totalIndicatorLength)
53+
throw new ArgumentException($"{nameof(sectionLength)} must be greater than the total length of {nameof(leftIndicator)} and {nameof(rightIndicator)}", nameof(sectionLength));
54+
4855
List<StringSection> sections = new List<StringSection>();
4956

5057
if (string.IsNullOrEmpty(fullString))
@@ -65,12 +72,12 @@ public static StringSections FromString(string fullString, int sectionLength, Co
6572
curSecBuilder.Append(fullString[i]);
6673

6774
// If the section is less than the smallest possible section size, skip processing
68-
if (curSecBuilder.Length < sectionLength - ((leftIndicator?.Length ?? 0) + (rightIndicator?.Length ?? 0))) continue;
75+
if (curSecBuilder.Length < sectionLength - totalIndicatorLength) continue;
6976

7077
// Decide what the left indicator text should be accounting for the leftmost section
7178
ColoredMessage leftIndicatorSection = sections.Count > 0 ? leftIndicator : null;
7279
// Decide what the right indicator text should be accounting for the rightmost section
73-
ColoredMessage rightIndicatorSection = i < fullString.Length - (1 + (rightIndicator?.Length ?? 0)) ? rightIndicator : null;
80+
ColoredMessage rightIndicatorSection = i < fullString.Length - (1 + rightIndicatorLength) ? rightIndicator : null;
7481

7582
// Check the section length against the final section length
7683
if (curSecBuilder.Length >= sectionLength - ((leftIndicatorSection?.Length ?? 0) + (rightIndicatorSection?.Length ?? 0)))

MultiAdminTests/ServerIO/StringSectionsTests.cs

Lines changed: 49 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,70 @@
1+
using System;
12
using Microsoft.VisualStudio.TestTools.UnitTesting;
3+
using MultiAdmin.ConsoleTools;
24
using MultiAdmin.ServerIO;
35

46
namespace MultiAdminTests.ServerIO
57
{
68
[TestClass]
79
public class StringSectionsTests
810
{
11+
private struct FromStringTemplate
12+
{
13+
public readonly string testString;
14+
public readonly string[] expectedSections;
15+
16+
public readonly int sectionLength;
17+
public readonly ColoredMessage leftIndictator;
18+
public readonly ColoredMessage rightIndictator;
19+
20+
public FromStringTemplate(string testString, string[] expectedSections, int sectionLength, ColoredMessage leftIndictator = null, ColoredMessage rightIndictator = null)
21+
{
22+
this.testString = testString;
23+
this.expectedSections = expectedSections;
24+
25+
this.sectionLength = sectionLength;
26+
this.leftIndictator = leftIndictator;
27+
this.rightIndictator = rightIndictator;
28+
}
29+
}
30+
931
[TestMethod]
1032
public void FromStringTest()
1133
{
12-
string[] expectedSections =
34+
try
1335
{
14-
"te",
15-
"st",
16-
" s",
17-
"tr",
18-
"in",
19-
"g"
36+
StringSections.FromString("test string", 2, new ColoredMessage("."), new ColoredMessage("."));
37+
Assert.Fail("This case should not be allowed, no further characters can be output because of the prefix and suffix");
38+
}
39+
catch (ArgumentException)
40+
{
41+
// Expected behaviour
42+
}
43+
44+
FromStringTemplate[] sectionTests =
45+
{
46+
new FromStringTemplate("test string", new string[] {"te", "st", " s", "tr", "in", "g"}, 2),
47+
new FromStringTemplate("test string", new string[] {"tes..", ".t ..", ".st..", ".ring"}, 5, new ColoredMessage("."), new ColoredMessage(".."))
2048
};
2149

22-
StringSections sections = StringSections.FromString("test string", 2);
50+
for (int i = 0; i < sectionTests.Length; i++)
51+
{
52+
FromStringTemplate sectionTest = sectionTests[i];
53+
54+
StringSections sections = StringSections.FromString(sectionTest.testString, sectionTest.sectionLength, sectionTest.leftIndictator, sectionTest.rightIndictator);
2355

24-
Assert.IsNotNull(sections);
25-
Assert.IsNotNull(sections.Sections);
56+
Assert.IsNotNull(sections);
57+
Assert.IsNotNull(sections.Sections);
2658

27-
Assert.IsTrue(sections.Sections.Length == expectedSections.Length, $"Expected sections length \"{expectedSections.Length}\", got \"{sections.Sections.Length}\"");
59+
Assert.IsTrue(sections.Sections.Length == sectionTest.expectedSections.Length, $"Failed at index {i}: Expected sections length \"{sectionTest.expectedSections.Length}\", got \"{sections.Sections.Length}\"");
2860

29-
for (int i = 0; i < expectedSections.Length; i++)
30-
{
31-
string expected = expectedSections[i];
32-
string result = sections.Sections[i].Text?.text;
61+
for (int j = 0; j < sectionTest.expectedSections.Length; j++)
62+
{
63+
string expected = sectionTest.expectedSections[j];
64+
string result = sections.Sections[j].Section.GetText();
3365

34-
Assert.AreEqual(expected, result, $"Failed at section index {i}: Expected section text to be \"{expected ?? "null"}\", got \"{result ?? "null"}\"");
66+
Assert.AreEqual(expected, result, $"Failed at index {i}: Failed at section index {j}: Expected section text to be \"{expected ?? "null"}\", got \"{result ?? "null"}\"");
67+
}
3568
}
3669
}
3770
}

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ Any configuration files within the directory defined by `servers_folder` will ha
6666
Config Option | Value Type | Default Value | Description
6767
--- | :---: | :---: | :------:
6868
config_location | String | **Empty** | The default location for the game to use for storing configuration files (a directory)
69+
appdata_location | String | **Empty** | The location for the game to use for AppData (a directory)
6970
disable_config_validation | Boolean | False | Disable the config validator
7071
share_non_configs | Boolean | True | Makes all files other than the config files store in AppData
7172
multiadmin_nolog | Boolean | False | Disable logging to file

0 commit comments

Comments
 (0)