GameSDKcraft/GamecraftRPC/CallbackUtility.cs

197 lines
6.7 KiB
C#

using System;
using System.Security.Cryptography;
using System.Text;
using GamecraftModdingAPI.App;
using GamecraftModdingAPI.Utility;
namespace GamecraftRPC
{
public static class CallbackUtility
{
private const int SALT_BYTE_LENGTH = 256;
private const string STATE_IN_GAME = "In Game";
private const string STATE_IN_MENU = "In Menu";
private const string DEETS_SIM = "Playing ";
private const string DEETS_BUILD = "Building ";
private const string DEETS_MENU = null;
private static RandomNumberGenerator random = RandomNumberGenerator.Create();
private static long lastUserJoinRequest = 0;
public static void GameEnter(object sender, GameEventArgs data)
{
PresenceUtility.LastGameStart = (ulong)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds;
if (PresenceUtility.IsConnecting && PresenceUtility.Lobby.HasValue)
{
PresenceUtility.IsConnecting = false;
ConnectToGamecraftPeer(PresenceUtility.Lobby.Value);
}
else
{
Plugin.SetDiscordActivity(
state: STATE_IN_GAME,
details: DEETS_BUILD + data.GameName,
partyMaxSize: 0,
partyCurrentSize: 0,
start: (long)PresenceUtility.LastGameStart,
debug: "GameEnter-API-callback"
);
CreateLobby();
}
}
public static void MenuEnter(object sender, MenuEventArgs data)
{
if (PresenceUtility.IsConnecting) return;
PresenceUtility.LastGameStart = 0;
PresenceUtility.Activity.Timestamps.Start = 0;
PresenceUtility.Activity.Timestamps.End = 0;
PresenceUtility.Activity.Party.Id = null;
PresenceUtility.Activity.Party.Size.CurrentSize = 0;
PresenceUtility.Activity.Party.Size.MaxSize = 0;
PresenceUtility.Activity.Details = DEETS_MENU;
PresenceUtility.Activity.State = STATE_IN_MENU;
PresenceUtility.Activity.Secrets.Join = null;
if (PresenceUtility.Lobby.HasValue && Plugin.DiscordRPC != null)
{
if (PresenceUtility.IsActivityHost)
{
Plugin.DiscordRPC.GetLobbyManager().DeleteLobby(PresenceUtility.Lobby.Value.Id, NobodyCares);
}
else
{
Plugin.DiscordRPC.GetLobbyManager().DisconnectLobby(PresenceUtility.Lobby.Value.Id, NobodyCares);
}
PresenceUtility.Lobby = null;
}
PresenceUtility.IsActivityHost = false;
PresenceUtility.IsServerActive = false;
Plugin.SetDiscordActivity(PresenceUtility.Activity, debug: "MenuEnter-API-callback");
}
public static void SimulationEnter(object sender, GameEventArgs data)
{
PresenceUtility.Activity.Details = DEETS_SIM + data.GameName;
Plugin.SetDiscordActivity(PresenceUtility.Activity, debug: "SimulationEnter-API-callback");
}
public static void BuildEnter(object sender, GameEventArgs data)
{
PresenceUtility.Activity.Details = DEETS_BUILD + data.GameName;
Plugin.SetDiscordActivity(PresenceUtility.Activity, debug: "BuildEnter-API-callback");
}
private static void CreateLobby()
{
if (Plugin.DiscordRPC == null) return;
Discord.LobbyManager lm = Plugin.DiscordRPC.GetLobbyManager();
Discord.LobbyTransaction lt = lm.GetLobbyCreateTransaction();
lt.SetMetadata("steamid", PresenceUtility.SteamId.ToString());
lt.SetType(Discord.LobbyType.Public);
lt.SetCapacity(2);
lm.CreateLobby(lt, SyncActivityLobby);
PresenceUtility.IsActivityHost = true;
}
public static void ActivityJoin(string secret)
{
Discord.LobbyManager lm = Plugin.DiscordRPC.GetLobbyManager();
if (PresenceUtility.Lobby.HasValue)
{
lm.DeleteLobby(PresenceUtility.Lobby.Value.Id, NobodyCares);
PresenceUtility.Lobby = null;
}
PresenceUtility.IsActivityHost = false;
PresenceUtility.IsServerActive = false;
lm.ConnectLobbyWithActivitySecret(secret, ConnectToGamecraftServerFromLobby);
lastUserJoinRequest = 0;
//Logging.MetaLog($"Received activity join");
}
public static void ActivityJoinRequest(ref Discord.User user)
{
lastUserJoinRequest = user.Id;
Logging.MetaLog($"Received activity join request from {user.Username}");
}
public static void ActivityInvite(Discord.ActivityActionType Type, ref Discord.User user, ref Discord.Activity activity)
{
if (Type == Discord.ActivityActionType.Join)
{
Logging.MetaLog($"Received invite to join {activity.Secrets.Join} from {user.Username}");
}
}
private static void SyncActivityLobby(Discord.Result result, ref Discord.Lobby lobby)
{
Discord.LobbyManager lm = Plugin.DiscordRPC.GetLobbyManager();
PresenceUtility.Lobby = lobby;
int lobbySize = lm.MemberCount(lobby.Id);
Logging.MetaLog($"Lobby {lobby.Id} ({lobbySize}/{lobby.Capacity} players)");
// TODO sync lobby info to activity
PresenceUtility.Activity.Secrets.Join = lm.GetLobbyActivitySecret(lobby.Id);
Logging.MetaLog($"Secret is now {PresenceUtility.Activity.Secrets.Join}");
PresenceUtility.Activity.Party.Id = lobby.Id.ToString();
int currentSize = PresenceUtility.PlayerCount > 0 ? (int)PresenceUtility.PlayerCount : lobbySize;
PresenceUtility.Activity.Party.Size.CurrentSize = currentSize;
PresenceUtility.Activity.Party.Size.MaxSize = currentSize * 2;
Plugin.SetDiscordActivity(PresenceUtility.Activity, debug: "SyncActivityLobby-Discord-callback");
}
private static void ConnectToGamecraftServerFromLobby(Discord.Result result, ref Discord.Lobby lobby)
{
SyncActivityLobby(result, ref lobby);
Client client = new Client();
if (client.InMenu)
{
PresenceUtility.IsConnecting = true;
client.MyGames[0].EnterGame();
}
else
{
ConnectToGamecraftPeer(lobby);
}
}
private static void ConnectToGamecraftPeer(Discord.Lobby lobby)
{
Discord.LobbyManager lm = Plugin.DiscordRPC.GetLobbyManager();
string steamId = lm.GetLobbyMetadataValue(lobby.Id, "steamid");
Logging.MetaLog($"Joined lobby from request, now joining server hosted by {steamId}");
GamecraftModdingAPI.Commands.CommandBuilder.Builder()
.Name("ConnectToCreativeServer")
.FromExisting<string>()
.Invoke(steamId);
}
public static void DiscordUserJoin(long lobbyId, long userId)
{
if (PresenceUtility.IsActivityHost)
{
if (!PresenceUtility.IsServerActive)
{
Logging.MetaLog("First user connected -- starting server");
GamecraftModdingAPI.Commands.CommandBuilder.Builder()
.Name("StartDefaultServer")
.FromExisting()
.Invoke();
PresenceUtility.IsServerActive = true;
}
}
}
public static void NobodyCares(Discord.Result result)
{
}
}
}