Skip to content

Commit

Permalink
Fix NREs in DiscordService.
Browse files Browse the repository at this point in the history
Handle the client being null. Previously, a service could be created with a null client. This would leads to NREs when invoking the static Update methods. Now we provide a static helper to get the instance created for the mod. This avoids two instances of the DiscordService being created (a static one, and an instance created in the mod manifest).
  • Loading branch information
RoosterDragon committed Feb 4, 2024
1 parent 4e031a6 commit 8c83b15
Show file tree
Hide file tree
Showing 7 changed files with 39 additions and 51 deletions.
59 changes: 20 additions & 39 deletions OpenRA.Mods.Common/DiscordService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,28 +33,9 @@ public sealed class DiscordService : IGlobalModData, IDisposable
{
public readonly string ApplicationId = null;
public readonly string Tooltip = "Open Source real-time strategy game engine for early Westwood titles.";
DiscordRpcClient client;
readonly DiscordRpcClient client;
DiscordState currentState;

static DiscordService instance;
static DiscordService Service
{
get
{
if (instance != null)
return instance;

if (!Game.Settings.Game.EnableDiscordService)
return null;

if (!Game.ModData.Manifest.Contains<DiscordService>())
return null;

instance = Game.ModData.Manifest.Get<DiscordService>();
return instance;
}
}

public DiscordService(MiniYaml yaml)
{
FieldLoader.Load(this, yaml);
Expand Down Expand Up @@ -100,12 +81,12 @@ void OnJoin(object sender, JoinMessage args)
Game.RunAfterTick(() => Game.RemoteDirectConnect(new ConnectionTarget(server[0], Exts.ParseInt32Invariant(server[1]))));
}

void SetStatus(DiscordState state, string details = null, string secret = null, int? players = null, int? slots = null)
public void UpdateStatus(DiscordState state, string details = null, string secret = null, int? players = null, int? slots = null)
{
if (currentState == state)
if (client == null)
return;

if (instance == null)
if (currentState == state)
return;

string stateText;
Expand Down Expand Up @@ -190,8 +171,11 @@ void SetStatus(DiscordState state, string details = null, string secret = null,
currentState = state;
}

void UpdateParty(int players, int slots)
public void UpdatePlayers(int players, int slots)
{
if (client == null)
return;

if (client.CurrentPresence.Party != null)
{
client.UpdatePartySize(players, slots);
Expand All @@ -206,29 +190,26 @@ void UpdateParty(int players, int slots)
});
}

public void Dispose()
public void UpdateDetails(string details)
{
if (client != null)
{
client.Dispose();
client = null;
instance = null;
}
}
if (client == null)
return;

public static void UpdateStatus(DiscordState state, string details = null, string secret = null, int? players = null, int? slots = null)
{
Service?.SetStatus(state, details, secret, players, slots);
client.UpdateDetails(details);
}

public static void UpdatePlayers(int players, int slots)
public void Dispose()
{
Service?.UpdateParty(players, slots);
client?.Dispose();
}

public static void UpdateDetails(string details)
public static DiscordService Get(ModData modData)
{
Service?.client.UpdateDetails(details);
var manifest = modData.Manifest;
if (manifest.Contains<DiscordService>())
return manifest.Get<DiscordService>();
else
return null;
}
}
}
2 changes: 1 addition & 1 deletion OpenRA.Mods.Common/Widgets/Logic/Ingame/IngameMenuLogic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -583,7 +583,7 @@ void OnConfirm()
Game.LoadShellMap();
else
{
DiscordService.UpdateStatus(DiscordState.InMapEditor);
DiscordService.Get(modData)?.UpdateStatus(DiscordState.InMapEditor);
Game.LoadEditor(map);
}
}
Expand Down
12 changes: 8 additions & 4 deletions OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyLogic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -855,6 +855,10 @@ void UpdatePlayerList()

void UpdateDiscordStatus()
{
var discordService = DiscordService.Get(modData);
if (discordService == null)
return;

var numberOfPlayers = 0;
var slots = 0;

Expand Down Expand Up @@ -889,15 +893,15 @@ void UpdateDiscordStatus()

var state = skirmishMode ? DiscordState.InSkirmishLobby : DiscordState.InMultiplayerLobby;

DiscordService.UpdateStatus(state, details, secret, numberOfPlayers, slots);
discordService.UpdateStatus(state, details, secret, numberOfPlayers, slots);
updateDiscordStatus = false;
}
else
{
if (!skirmishMode)
DiscordService.UpdatePlayers(numberOfPlayers, slots);
discordService.UpdatePlayers(numberOfPlayers, slots);

DiscordService.UpdateDetails(details);
discordService.UpdateDetails(details);
}
}

Expand Down Expand Up @@ -930,7 +934,7 @@ void OnGameStart()

var state = skirmishMode ? DiscordState.PlayingSkirmish : DiscordState.PlayingMultiplayer;
var details = map.Title + " - " + orderManager.LobbyInfo.GlobalSettings.ServerName;
DiscordService.UpdateStatus(state, details);
DiscordService.Get(modData)?.UpdateStatus(state, details);

onStart();
}
Expand Down
8 changes: 4 additions & 4 deletions OpenRA.Mods.Common/Widgets/Logic/MainMenuLogic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ void SwitchMenu(MenuType type)
{
menuType = type;

DiscordService.UpdateStatus(DiscordState.InMenu);
DiscordService.Get(modData)?.UpdateStatus(DiscordState.InMenu);

// Update button mouseover
Game.RunAfterTick(Ui.ResetTooltips);
Expand Down Expand Up @@ -286,7 +286,7 @@ void OnSysInfoComplete()

Game.OnShellmapLoaded += OpenMenuBasedOnLastGame;

DiscordService.UpdateStatus(DiscordState.InMenu);
DiscordService.Get(modData)?.UpdateStatus(DiscordState.InMenu);
}

void LoadAndDisplayNews(WebServices webServices, Widget newsBG)
Expand Down Expand Up @@ -366,11 +366,11 @@ void OnRemoteDirectConnect(ConnectionTarget endpoint)
});
}

static void LoadMapIntoEditor(string uid)
void LoadMapIntoEditor(string uid)
{
Game.LoadEditor(uid);

DiscordService.UpdateStatus(DiscordState.InMapEditor);
DiscordService.Get(modData)?.UpdateStatus(DiscordState.InMapEditor);

lastGameState = MenuPanel.MapEditor;
}
Expand Down
2 changes: 1 addition & 1 deletion OpenRA.Mods.Common/Widgets/Logic/MissionBrowserLogic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ void OnGameStart()
{
Ui.CloseWindow();

DiscordService.UpdateStatus(DiscordState.PlayingCampaign);
DiscordService.Get(modData)?.UpdateStatus(DiscordState.PlayingCampaign);

onStart();
}
Expand Down
5 changes: 4 additions & 1 deletion OpenRA.Mods.Common/Widgets/Logic/MultiplayerLogic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,16 @@ public class MultiplayerLogic : ChromeLogic
{
static readonly Action DoNothing = () => { };

readonly ModData modData;
readonly Action onStart;
readonly Action onExit;
readonly ServerListLogic serverListLogic;

[ObjectCreator.UseCtor]
public MultiplayerLogic(Widget widget, ModData modData, Action onStart, Action onExit, ConnectionTarget directConnectEndPoint)
{
this.modData = modData;

// MultiplayerLogic is a superset of the ServerListLogic
// but cannot be a direct subclass because it needs to pass object-level state to the constructor
serverListLogic = new ServerListLogic(widget, modData, Join);
Expand Down Expand Up @@ -96,7 +99,7 @@ void OnLobbyExit()

Game.Disconnect();

DiscordService.UpdateStatus(DiscordState.InMenu);
DiscordService.Get(modData)?.UpdateStatus(DiscordState.InMenu);
}

Game.OpenWindow("SERVER_LOBBY", new WidgetArgs
Expand Down
2 changes: 1 addition & 1 deletion OpenRA.Mods.Common/Widgets/Logic/ReplayBrowserLogic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -777,7 +777,7 @@ void WatchReplay()
{
cancelLoadingReplays = true;

DiscordService.UpdateStatus(DiscordState.WatchingReplay);
DiscordService.Get(modData)?.UpdateStatus(DiscordState.WatchingReplay);

Game.JoinReplay(selectedReplay.FilePath);
}
Expand Down

0 comments on commit 8c83b15

Please sign in to comment.