add plugin loading and game modes

This commit is contained in:
in0finite 2021-02-19 02:22:03 +01:00
parent 44ccd57fd3
commit ec436c6037
7 changed files with 203 additions and 4 deletions

View file

@ -27,6 +27,8 @@ GameObject:
- component: {fileID: 5853763562556677784}
- component: {fileID: 7588617501852694525}
- component: {fileID: 6547606932669875539}
- component: {fileID: 8970227709208402880}
- component: {fileID: 3898620812402470502}
m_Layer: 0
m_Name: GameManager
m_TagString: Untagged
@ -352,3 +354,27 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 28b5c4d8f70199a438f3c28f59d87264, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!114 &8970227709208402880
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1297494511425690}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 37e62fd808355224f8f300f0f87734d9, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!114 &3898620812402470502
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1297494511425690}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: aabf0ed3019cb714e9079ac483b9a670, type: 3}
m_Name:
m_EditorClassIdentifier:

View file

@ -0,0 +1,54 @@
using System;
using System.Collections.Generic;
using UnityEngine;
namespace SanAndreasUnity.Behaviours
{
public class GameModeManager : MonoBehaviour
{
public static GameModeManager Instance { get; private set; }
public class GameModeInfo
{
public string Name { get; }
public string Description { get; }
public System.Action ActivationCallback { get; }
public GameModeInfo(string name, string description, Action activationCallback)
{
Name = name;
Description = description;
ActivationCallback = activationCallback;
}
}
List<GameModeInfo> m_gameModes = new List<GameModeInfo>();
public IReadOnlyList<GameModeInfo> GameModes => m_gameModes;
private GameModeInfo m_activeGameMode;
void Awake()
{
Instance = this;
}
public void RegisterGameMode(GameModeInfo gameModeInfo)
{
m_gameModes.Add(gameModeInfo);
}
public void ActivateGameMode(GameModeInfo gameModeInfo)
{
if (m_activeGameMode != null)
{
if (m_activeGameMode == gameModeInfo)
throw new Exception($"Can not activate game mode '{gameModeInfo.Name}' because it is already activated");
throw new Exception($"Can not activate game mode '{gameModeInfo.Name}' because another one ('{m_activeGameMode.Name}') is already activated");
}
m_activeGameMode = gameModeInfo;
gameModeInfo.ActivationCallback();
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: aabf0ed3019cb714e9079ac483b9a670
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,66 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using SanAndreasUnity.Utilities;
using UnityEngine;
namespace SanAndreasUnity.Behaviours
{
public class PluginManager : MonoBehaviour
{
public static string[] PluginDirectories => new []
{
#if UNITY_EDITOR
Path.Combine(Application.dataPath, "../SAU_Plugins"),
#else
Path.Combine(Application.dataPath, "Plugins"),
#endif
};
void Awake()
{
F.RunExceptionSafe(LoadPlugins, $"Error while loading plugins: ");
}
void LoadPlugins()
{
// find all plugins
var allFiles = new List<string>();
foreach (string pluginsDirectory in PluginDirectories)
{
if (!Directory.Exists(pluginsDirectory))
continue;
var filePaths = Directory.GetFiles(pluginsDirectory, "*.dll", SearchOption.TopDirectoryOnly);
// sort files manually to prevent undefined behavior
Array.Sort(filePaths);
allFiles.AddRange(filePaths);
}
//allFiles.RemoveAll(path => !path.EndsWith(".json", StringComparison.InvariantCultureIgnoreCase) || !path.EndsWith(".dll", StringComparison.InvariantCultureIgnoreCase));
int numLoaded = 0;
foreach (string pluginFilePath in allFiles)
{
if (LoadPlugin(pluginFilePath))
numLoaded++;
}
if (allFiles.Count > 0)
Debug.Log($"Loaded {numLoaded}/{allFiles.Count} plugins");
}
bool LoadPlugin(string pluginFilePath)
{
return F.RunExceptionSafe(
() => Assembly.LoadFrom(pluginFilePath),
$"error loading plugin from '{pluginFilePath}': ");
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 37e62fd808355224f8f300f0f87734d9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -1,4 +1,6 @@
using System.Collections.Generic;
using System.Linq;
using SanAndreasUnity.Behaviours;
using UnityEngine;
using SanAndreasUnity.Utilities;
using SanAndreasUnity.Net;
@ -13,7 +15,7 @@ namespace SanAndreasUnity.UI
bool m_dedicatedServer = false;
string m_maxNumPlayersStr = "40";
[SerializeField] string[] m_availableScenes = new string[0];
int m_selectedSceneIndex = 0;
int m_selectedModeIndex = 0;
bool m_registerAtMasterServer = false;
public int width = 550;
@ -60,8 +62,12 @@ namespace SanAndreasUnity.UI
GUILayout.Label("Max num players:");
m_maxNumPlayersStr = GUILayout.TextField(m_maxNumPlayersStr, GUILayout.Width(100));
GUILayout.Label("Map:");
m_selectedSceneIndex = GUILayout.SelectionGrid(m_selectedSceneIndex, m_availableScenes, this.mapSelectionGridXCount, GUILayout.MinHeight(this.minMapButtonHeight));
GUILayout.Label("Game mode:");
m_selectedModeIndex = GUILayout.SelectionGrid(
m_selectedModeIndex,
m_availableScenes.Concat(GameModeManager.Instance.GameModes.Select(gm => gm.Name)).ToArray(),
this.mapSelectionGridXCount,
GUILayout.MinHeight(this.minMapButtonHeight));
GUILayout.Space(5);
m_registerAtMasterServer = GUILayout.Toggle(m_registerAtMasterServer, "Register at master server");
@ -86,13 +92,24 @@ namespace SanAndreasUnity.UI
try
{
ushort port = ushort.Parse(m_portStr);
string scene = m_availableScenes[m_selectedSceneIndex];
string scene = m_selectedModeIndex < m_availableScenes.Length
? m_availableScenes[m_selectedModeIndex]
: m_availableScenes[0];
ushort maxNumPlayers = ushort.Parse(m_maxNumPlayersStr);
MasterServerClient.Instance.IsServerRegistrationEnabled = m_registerAtMasterServer;
NetManager.StartServer(port, scene, maxNumPlayers, m_dedicatedServer, m_dontListen);
// activate game mode if it is selected
if (m_selectedModeIndex >= m_availableScenes.Length)
{
var gm = GameModeManager.Instance.GameModes[m_availableScenes.Length - m_selectedModeIndex];
F.RunExceptionSafe(
() => GameModeManager.Instance.ActivateGameMode(gm),
$"Error while activating game mode '{gm.Name}': ");
}
}
catch (System.Exception ex)
{

View file

@ -396,6 +396,20 @@ namespace SanAndreasUnity.Utilities
}
public static bool RunExceptionSafe (System.Action function, string errorMessagePrefix)
{
try {
function();
return true;
} catch(System.Exception ex) {
try {
Debug.LogError (errorMessagePrefix + ex);
} catch {}
}
return false;
}
public static void RunExceptionSafe (System.Action function)
{
try {