Skip to content

Commit

Permalink
Updated and fixed the networking code for the admin menu.
Browse files Browse the repository at this point in the history
  • Loading branch information
8vogt committed Nov 26, 2020
1 parent e108965 commit 180c7af
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 31 deletions.
8 changes: 6 additions & 2 deletions SEWorldGenPlugin/GUI/PluginAdminMenu.cs
Original file line number Diff line number Diff line change
Expand Up @@ -705,7 +705,11 @@ private void OnAddRingToPlanetButton(MyGuiControlButton button)
}
else
{
SystemGenerator.Static.AddRingToPlanet(m_selectedPlanet.DisplayName, item);
SystemGenerator.Static.AddRingToPlanet(m_selectedPlanet.DisplayName, item, delegate (bool success)
{
LoadPlanetsInWorld(m_selectedPlanet.DisplayName);
PlanetListItemClicked(m_planetListBox);
});
}
LoadPlanetsInWorld(m_selectedPlanet.DisplayName);
PlanetListItemClicked(m_planetListBox);
Expand All @@ -730,7 +734,6 @@ private void OnRemoveRingFromPlanetButton(MyGuiControlButton button)
SystemGenerator.Static.RemoveRingFromPlanet(m_selectedPlanet.DisplayName);
}
LoadPlanetsInWorld(m_selectedPlanet.DisplayName);
PlanetListItemClicked(m_planetListBox);
}
}

Expand Down Expand Up @@ -860,6 +863,7 @@ private void LoadPlanetsInWorld(string selectPlanet = null)
if(selectPlanet != null && name.Equals(selectPlanet))
{
m_planetListBox.SelectSingleItem(m_planetListBox.Items[m_planetListBox.Items.Count - 1]);
PlanetListItemClicked(m_planetListBox);
}
}
}
Expand Down
81 changes: 58 additions & 23 deletions SEWorldGenPlugin/Generator/SystemGenerator.Networking.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,18 @@ namespace SEWorldGenPlugin.Generator
/// </summary>
public partial class SystemGenerator
{
private Dictionary<ulong, Action<bool, MySystemItem>> m_getCallbacks;
private Dictionary<ulong, Action<bool, MySystemItem>> m_getActionCallbacks;
private Dictionary<ulong, Action<bool>> m_addActionsCallbacks;
private ulong m_currentIndex;
private ulong m_currentAddIndex;

/// <summary>
/// Initializes a list for callbacks, for networking actions.
/// </summary>
private void InitNet()
{
m_getCallbacks = new Dictionary<ulong, Action<bool, MySystemItem>>();
m_getActionCallbacks = new Dictionary<ulong, Action<bool, MySystemItem>>();
m_addActionsCallbacks = new Dictionary<ulong, Action<bool>>();
}

/// <summary>
Expand All @@ -38,7 +41,8 @@ private void LoadNet()
private void UnloadNet()
{
m_currentIndex = 0;
m_getCallbacks = null;
m_getActionCallbacks = null;
m_addActionsCallbacks = null;
}

/// <summary>
Expand All @@ -48,36 +52,39 @@ private void UnloadNet()
/// <param name="callback"></param>
public void GetObject(string name, Action<bool, MySystemItem> callback)
{
m_getCallbacks.Add(++m_currentIndex, callback);
m_getActionCallbacks.Add(++m_currentIndex, callback);
PluginEventHandler.Static.RaiseStaticEvent(SendGetServer, Sync.MyId, name, m_currentIndex, null);
}

/// <summary>
/// Adds a planet to the system on the server.
/// </summary>
/// <param name="planet">Planet to add</param>
public void AddPlanet(MyPlanetItem planet)
public void AddPlanet(MyPlanetItem planet, Action<bool> callback = null)
{
PluginEventHandler.Static.RaiseStaticEvent(SendAddPlanet, planet, null);
m_addActionsCallbacks.Add(++m_currentAddIndex, callback);
PluginEventHandler.Static.RaiseStaticEvent(SendAddPlanet, planet, m_currentAddIndex, Sync.MyId, null);
}

/// <summary>
/// Adds a ring to a planet on the server.
/// </summary>
/// <param name="name">Name of the planet to add the ring to</param>
/// <param name="ring">Ring data to add</param>
public void AddRingToPlanet(string name, MyPlanetRingItem ring)
public void AddRingToPlanet(string name, MyPlanetRingItem ring, Action<bool> callback = null)
{
PluginEventHandler.Static.RaiseStaticEvent(SendAddRingToPlanet, name, ring, null);
m_addActionsCallbacks.Add(++m_currentAddIndex, callback);
PluginEventHandler.Static.RaiseStaticEvent(SendAddRingToPlanet, name, ring, m_currentAddIndex, Sync.MyId, null);
}

/// <summary>
/// Removes the asteroid ring from a planet on the server
/// </summary>
/// <param name="name">Name of the ring</param>
public void RemoveRingFromPlanet(string name)
public void RemoveRingFromPlanet(string name, Action<bool> callback = null)
{
PluginEventHandler.Static.RaiseStaticEvent(SendRemoveRingFromPlanet, name, null);
m_addActionsCallbacks.Add(++m_currentAddIndex, callback);
PluginEventHandler.Static.RaiseStaticEvent(SendRemoveRingFromPlanet, name, m_currentAddIndex, Sync.MyId, null);
}

/// <summary>
Expand Down Expand Up @@ -124,8 +131,8 @@ static void SendGetServer(ulong client, string name, ulong callback)
[Client]
static void SendGetPlanetClient(bool success, MyPlanetItem item, ulong callback)
{
Static.m_getCallbacks[callback](success, item);
Static.m_getCallbacks.Remove(callback);
Static.m_getActionCallbacks[callback](success, item);
Static.m_getActionCallbacks.Remove(callback);
}

/// <summary>
Expand All @@ -135,12 +142,11 @@ static void SendGetPlanetClient(bool success, MyPlanetItem item, ulong callback)
/// <param name="item">The moon item</param>
/// <param name="callback">Callback id of the callback to call</param>
[Event(102)]

[Client]
static void SendGetMoonClient(bool success, MyPlanetMoonItem item, ulong callback)
{
Static.m_getCallbacks[callback](success, item);
Static.m_getCallbacks.Remove(callback);
Static.m_getActionCallbacks[callback](success, item);
Static.m_getActionCallbacks.Remove(callback);
}

/// <summary>
Expand All @@ -153,8 +159,8 @@ static void SendGetMoonClient(bool success, MyPlanetMoonItem item, ulong callbac
[Client]
static void SendGetBeltClient(bool success, MySystemBeltItem item, ulong callback)
{
Static.m_getCallbacks[callback](success, item);
Static.m_getCallbacks.Remove(callback);
Static.m_getActionCallbacks[callback](success, item);
Static.m_getActionCallbacks.Remove(callback);
}

/// <summary>
Expand All @@ -167,8 +173,8 @@ static void SendGetBeltClient(bool success, MySystemBeltItem item, ulong callbac
[Client]
static void SendGetRingClient(bool success, MyPlanetRingItem item, ulong callback)
{
Static.m_getCallbacks[callback](success, item);
Static.m_getCallbacks.Remove(callback);
Static.m_getActionCallbacks[callback](success, item);
Static.m_getActionCallbacks.Remove(callback);
}

/// <summary>
Expand All @@ -177,9 +183,8 @@ static void SendGetRingClient(bool success, MyPlanetRingItem item, ulong callbac
/// <param name="planetName">Name of the planet</param>
/// <param name="ringBase">Ring item to add to the planet</param>
[Event(105)]

[Server]
static void SendAddRingToPlanet(string planetName, MyPlanetRingItem ringBase)
static void SendAddRingToPlanet(string planetName, MyPlanetRingItem ringBase, ulong callback, ulong client)
{
if(Static.TryGetObject(planetName, out MySystemItem obj))
{
Expand All @@ -190,9 +195,13 @@ static void SendAddRingToPlanet(string planetName, MyPlanetRingItem ringBase)
{
ringBase.Center = planet.CenterPosition;
planet.PlanetRing = ringBase;

PluginEventHandler.Static.RaiseStaticEvent(SendAddCallbackClient, true, callback, client);
return;
}
}
}
PluginEventHandler.Static.RaiseStaticEvent(SendAddCallbackClient, false, callback, client);
}

/// <summary>
Expand All @@ -201,7 +210,7 @@ static void SendAddRingToPlanet(string planetName, MyPlanetRingItem ringBase)
/// <param name="planet">Planet item to add</param>
[Event(106)]
[Server]
static void SendAddPlanet(MyPlanetItem planet)
static void SendAddPlanet(MyPlanetItem planet, ulong callback, ulong client)
{
if(planet != null)
{
Expand All @@ -218,7 +227,11 @@ static void SendAddPlanet(MyPlanetItem planet)
Static.Objects.Remove(obj);
}
Static.Objects.Add(planet);

PluginEventHandler.Static.RaiseStaticEvent(SendAddCallbackClient, true, callback, client);
return;
}
PluginEventHandler.Static.RaiseStaticEvent(SendAddCallbackClient, false, callback, client);
}

/// <summary>
Expand All @@ -228,7 +241,7 @@ static void SendAddPlanet(MyPlanetItem planet)
/// <param name="planetName">Name of the planet</param>
[Event(107)]
[Server]
static void SendRemoveRingFromPlanet(string planetName)
static void SendRemoveRingFromPlanet(string planetName, ulong callback, ulong client)
{
if (Static.TryGetObject(planetName, out MySystemItem obj))
{
Expand All @@ -238,9 +251,31 @@ static void SendRemoveRingFromPlanet(string planetName)
if (planet.PlanetRing != null)
{
planet.PlanetRing = null;
PluginEventHandler.Static.RaiseStaticEvent(SendAddCallbackClient, true, callback, client);
return;
}
}
}
PluginEventHandler.Static.RaiseStaticEvent(SendAddCallbackClient, false, callback, client);
}

/// <summary>
/// Client Event: Sends a boolean to the client to check if the add event was successfull.
/// </summary>
/// <param name="success">Whether or not the planet is valid</param>
/// <param name="item">The planet item</param>
/// <param name="callback">Callback id of the callback to call</param>
[Event(108)]
[Client]
static void SendAddCallbackClient(bool success, ulong callback)
{
if(Static.m_addActionsCallbacks[callback] == null)
{
Static.m_addActionsCallbacks.Remove(callback);
return;
}
Static.m_addActionsCallbacks[callback](success);
Static.m_addActionsCallbacks.Remove(callback);
}
}
}
69 changes: 64 additions & 5 deletions SEWorldGenPlugin/Networking/PluginEventHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,30 @@ public void RaiseStaticEvent<T1, T2, T3>(Action<T1, T2, T3> action, T1 arg1, T2
}
}

/// <summary>
/// Raises a static event, using arg1, arg2 and arg3 as a parameters, to be executed over network. It executes it on receiver, if it is not
/// marked as broadcast or server.
/// </summary>
/// <typeparam name="T1">The type of the first argument of the method that gets executed.</typeparam>
/// <typeparam name="T2">The type of the second argument of the method that gets executed.</typeparam>
/// <typeparam name="T3">The type of the third argument of the method that gets executed.</typeparam>
/// <typeparam name="T4">The type of the fourth argument of the method that gets executed.</typeparam>
/// <param name="action">The method to execute over network on the receiver</param>
/// <param name="arg1">The first method parameter</param>
/// <param name="arg2">The second method parameter</param>
/// <param name="arg3">The third method parameter</param>
/// <param name="arg4">The fourth method parameter</param>
/// <param name="receiver">Optional receiver, if the method is marked as client</param>
public void RaiseStaticEvent<T1, T2, T3, T4>(Action<T1, T2, T3, T4> action, T1 arg1, T2 arg2, T3 arg3, T4 arg4, ulong? receiver = null)
{
if (action.Method.CustomAttributes.Any(data => data.AttributeType == typeof(EventAttribute)))
{
ulong id = action.Method.GetCustomAttribute<EventAttribute>().Id;
byte[] data = PackData(id, arg1, arg2, arg3, arg4);
SendData(action.Method, data, receiver);
}
}

/// <summary>
/// Registers all methods in of the given class type with the EventOwner attribute, that are marked as events,
/// in the PluginHandler.
Expand Down Expand Up @@ -197,13 +221,17 @@ private void MessageHandler(ulong sender, byte[] data)
if(m_registeredMethods.TryGetValue(id, out MethodInfo info))
{
var parameters = info.GetParameters();
if (parameters.Length > 3) return;
Type[] args = new Type[3] { typeof(ProtoNull), typeof(ProtoNull), typeof(ProtoNull) };
if (parameters.Length > 4) return;
Type[] args = new Type[4] { typeof(ProtoNull), typeof(ProtoNull), typeof(ProtoNull), typeof(ProtoNull) };
for(int i = 0; i < parameters.Length; i++)
{
args[i] = parameters[i].ParameterType;
if(args[i] == null)
{
args[i] = typeof(ProtoNull);
}
}
object[] paras = new object[5] { data, null, null, null, null };
object[] paras = new object[6] { data, null, null, null, null, null};

m_unpackData.MakeGenericMethod(args).Invoke(this, paras);
List<object> objs = new List<object>();
Expand Down Expand Up @@ -242,6 +270,34 @@ private byte[] PackData<T1, T2, T3>(ulong id, T1 arg1, T2 arg2, T3 arg3)
}
}

/// <summary>
/// Packs the data for an event method into a serialized byte[].
/// The byte array starts with the methods event id and is followed by
/// the arguments of the method.
/// </summary>
/// <typeparam name="T1">The type of the first method parameter</typeparam>
/// <typeparam name="T2">The type of the second method parameter</typeparam>
/// <typeparam name="T3">The type of the third method parameter</typeparam>
/// <typeparam name="T4">The type of the fourth method parameter</typeparam>
/// <param name="id">The methods event id</param>
/// <param name="arg1">The methods first parameter</param>
/// <param name="arg2">The methods second parameter</param>
/// <param name="arg3">The methods third parameter</param>
/// <param name="arg4">The methods fourth parameter</param>
/// <returns>The byte[] of the packed data for the method.</returns>
private byte[] PackData<T1, T2, T3, T4>(ulong id, T1 arg1, T2 arg2, T3 arg3, T4 arg4)
{
using (var ms = new MemoryStream())
{
Serializer.SerializeWithLengthPrefix(ms, id, PrefixStyle.Base128);
Serializer.SerializeWithLengthPrefix(ms, arg1, PrefixStyle.Base128);
Serializer.SerializeWithLengthPrefix(ms, arg2, PrefixStyle.Base128);
Serializer.SerializeWithLengthPrefix(ms, arg3, PrefixStyle.Base128);
Serializer.SerializeWithLengthPrefix(ms, arg4, PrefixStyle.Base128);
return ms.ToArray();
}
}

/// <summary>
/// Retreives the methods event id from the packed data of a method
/// </summary>
Expand All @@ -261,19 +317,22 @@ private ulong GetId(byte[] data)
/// <typeparam name="T1">The type of the first method parameter</typeparam>
/// <typeparam name="T2">The type of the second method parameter</typeparam>
/// <typeparam name="T3">The type of the third method parameter</typeparam>
/// <typeparam name="T4">The type of the fourth method parameter</typeparam>
/// <param name="data">The packed data of the method</param>
/// <param name="id">Output value for the methods event id.</param>
/// <param name="arg1">Output value for the first method parameter.</param>
/// <param name="arg2">Output value for the second method parameter.</param>
/// <param name="arg3">Output value for the third method parameter.</param>
private void UnpackData<T1, T2, T3>(byte[] data, out ulong id, out T1 arg1, out T2 arg2, out T3 arg3)
/// <param name="arg4">Output value for the fourth method parameter.</param>
private void UnpackData<T1, T2, T3, T4>(byte[] data, out ulong id, out T1 arg1, out T2 arg2, out T3 arg3, out T4 arg4)
{
using(var ms = new MemoryStream(data))
using (var ms = new MemoryStream(data))
{
id = Serializer.DeserializeWithLengthPrefix<ulong>(ms, PrefixStyle.Base128);
arg1 = Serializer.DeserializeWithLengthPrefix<T1>(ms, PrefixStyle.Base128);
arg2 = Serializer.DeserializeWithLengthPrefix<T2>(ms, PrefixStyle.Base128);
arg3 = Serializer.DeserializeWithLengthPrefix<T3>(ms, PrefixStyle.Base128);
arg4 = Serializer.DeserializeWithLengthPrefix<T4>(ms, PrefixStyle.Base128);

return;
}
Expand Down
2 changes: 1 addition & 1 deletion SEWorldGenPlugin/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,5 @@
// Sie können alle Werte angeben oder Standardwerte für die Build- und Revisionsnummern verwenden,
// indem Sie "*" wie unten gezeigt eingeben:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.7.6.6")]
[assembly: AssemblyVersion("1.7.6.7")]
[assembly: AssemblyFileVersion("1.0.0")]

0 comments on commit 180c7af

Please sign in to comment.