You've already forked Darklings-FightingGame
mirror of
https://github.com/izzy2lost/Darklings-FightingGame.git
synced 2026-03-10 11:35:19 -07:00
335 lines
12 KiB
C#
335 lines
12 KiB
C#
|
|
using System;
|
||
|
|
using System.Runtime.InteropServices;
|
||
|
|
|
||
|
|
namespace UnityGGPO {
|
||
|
|
|
||
|
|
public enum GGPOPlayerType {
|
||
|
|
GGPO_PLAYERTYPE_LOCAL,
|
||
|
|
GGPO_PLAYERTYPE_REMOTE,
|
||
|
|
GGPO_PLAYERTYPE_SPECTATOR,
|
||
|
|
}
|
||
|
|
|
||
|
|
[Serializable]
|
||
|
|
public struct GGPOPlayer {
|
||
|
|
public GGPOPlayerType type;
|
||
|
|
public int player_num;
|
||
|
|
public string ip_address;
|
||
|
|
public ushort port;
|
||
|
|
|
||
|
|
public override string ToString() {
|
||
|
|
return $"({type},{player_num},{ip_address},{port})";
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public class GGPONetworkStats {
|
||
|
|
public int send_queue_len;
|
||
|
|
public int recv_queue_len;
|
||
|
|
public int ping;
|
||
|
|
public int kbps_sent;
|
||
|
|
public int local_frames_behind;
|
||
|
|
public int remote_frames_behind;
|
||
|
|
}
|
||
|
|
|
||
|
|
public static partial class GGPO {
|
||
|
|
private const string libraryName = "UnityGGPO";
|
||
|
|
|
||
|
|
public const int MAX_PLAYERS = 4;
|
||
|
|
public const int MAX_PREDICTION_FRAMES = 8;
|
||
|
|
public const int MAX_SPECTATORS = 32;
|
||
|
|
|
||
|
|
public const int OK = 0;
|
||
|
|
public const int INVALID_HANDLE = -1;
|
||
|
|
|
||
|
|
public const int ERRORCODE_SUCCESS = 0;
|
||
|
|
public const int ERRORCODE_GENERAL_FAILURE = -1;
|
||
|
|
public const int ERRORCODE_INVALID_SESSION = 1;
|
||
|
|
public const int ERRORCODE_INVALID_PLAYER_HANDLE = 2;
|
||
|
|
public const int ERRORCODE_PLAYER_OUT_OF_RANGE = 3;
|
||
|
|
public const int ERRORCODE_PREDICTION_THRESHOLD = 4;
|
||
|
|
public const int ERRORCODE_UNSUPPORTED = 5;
|
||
|
|
public const int ERRORCODE_NOT_SYNCHRONIZED = 6;
|
||
|
|
public const int ERRORCODE_IN_ROLLBACK = 7;
|
||
|
|
public const int ERRORCODE_INPUT_DROPPED = 8;
|
||
|
|
public const int ERRORCODE_PLAYER_DISCONNECTED = 9;
|
||
|
|
public const int ERRORCODE_TOO_MANY_SPECTATORS = 10;
|
||
|
|
public const int ERRORCODE_INVALID_REQUEST = 11;
|
||
|
|
|
||
|
|
public const int EVENTCODE_CONNECTED_TO_PEER = 1000;
|
||
|
|
public const int EVENTCODE_SYNCHRONIZING_WITH_PEER = 1001;
|
||
|
|
public const int EVENTCODE_SYNCHRONIZED_WITH_PEER = 1002;
|
||
|
|
public const int EVENTCODE_RUNNING = 1003;
|
||
|
|
public const int EVENTCODE_DISCONNECTED_FROM_PEER = 1004;
|
||
|
|
public const int EVENTCODE_TIMESYNC = 1005;
|
||
|
|
public const int EVENTCODE_CONNECTION_INTERRUPTED = 1006;
|
||
|
|
public const int EVENTCODE_CONNECTION_RESUMED = 1007;
|
||
|
|
|
||
|
|
public static bool SUCCEEDED(int result) {
|
||
|
|
return result == ERRORCODE_SUCCESS;
|
||
|
|
}
|
||
|
|
|
||
|
|
public static string GetErrorCodeMessage(int result) {
|
||
|
|
switch (result) {
|
||
|
|
case ERRORCODE_SUCCESS:
|
||
|
|
return "ERRORCODE_SUCCESS";
|
||
|
|
|
||
|
|
case ERRORCODE_GENERAL_FAILURE:
|
||
|
|
return "ERRORCODE_GENERAL_FAILURE";
|
||
|
|
|
||
|
|
case ERRORCODE_INVALID_SESSION:
|
||
|
|
return "ERRORCODE_INVALID_SESSION";
|
||
|
|
|
||
|
|
case ERRORCODE_INVALID_PLAYER_HANDLE:
|
||
|
|
return "ERRORCODE_INVALID_PLAYER_HANDLE";
|
||
|
|
|
||
|
|
case ERRORCODE_PLAYER_OUT_OF_RANGE:
|
||
|
|
return "ERRORCODE_PLAYER_OUT_OF_RANGE";
|
||
|
|
|
||
|
|
case ERRORCODE_PREDICTION_THRESHOLD:
|
||
|
|
return "ERRORCODE_PREDICTION_THRESHOLD";
|
||
|
|
|
||
|
|
case ERRORCODE_UNSUPPORTED:
|
||
|
|
return "ERRORCODE_UNSUPPORTED";
|
||
|
|
|
||
|
|
case ERRORCODE_NOT_SYNCHRONIZED:
|
||
|
|
return "ERRORCODE_NOT_SYNCHRONIZED";
|
||
|
|
|
||
|
|
case ERRORCODE_IN_ROLLBACK:
|
||
|
|
return "ERRORCODE_IN_ROLLBACK";
|
||
|
|
|
||
|
|
case ERRORCODE_INPUT_DROPPED:
|
||
|
|
return "ERRORCODE_INPUT_DROPPED";
|
||
|
|
|
||
|
|
case ERRORCODE_PLAYER_DISCONNECTED:
|
||
|
|
return "ERRORCODE_PLAYER_DISCONNECTED";
|
||
|
|
|
||
|
|
case ERRORCODE_TOO_MANY_SPECTATORS:
|
||
|
|
return "ERRORCODE_TOO_MANY_SPECTATORS";
|
||
|
|
|
||
|
|
case ERRORCODE_INVALID_REQUEST:
|
||
|
|
return "ERRORCODE_INVALID_REQUEST";
|
||
|
|
|
||
|
|
default:
|
||
|
|
return "INVALID_ERRORCODE";
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public static string Version {
|
||
|
|
get {
|
||
|
|
return Utils.GetString(UggPluginVersion());
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public static int BuildNumber {
|
||
|
|
get {
|
||
|
|
return UggPluginBuildNumber();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public delegate void LogDelegate(string text);
|
||
|
|
|
||
|
|
public delegate bool BeginGameDelegate(string text);
|
||
|
|
|
||
|
|
public delegate bool AdvanceFrameDelegate(int flags);
|
||
|
|
|
||
|
|
public unsafe delegate bool LoadGameStateDelegate(void* buffer, int length);
|
||
|
|
|
||
|
|
public unsafe delegate bool LogGameStateDelegate(string filename, void* buffer, int length);
|
||
|
|
|
||
|
|
public unsafe delegate bool SaveGameStateDelegate(void** buffer, int* len, int* checksum, int frame);
|
||
|
|
|
||
|
|
public unsafe delegate void FreeBufferDelegate(void* buffer);
|
||
|
|
|
||
|
|
public delegate bool OnEventDelegate(IntPtr evt);
|
||
|
|
|
||
|
|
[DllImport(libraryName, CharSet = CharSet.Ansi)]
|
||
|
|
private static extern IntPtr UggPluginVersion();
|
||
|
|
|
||
|
|
[DllImport(libraryName)]
|
||
|
|
private static extern int UggPluginBuildNumber();
|
||
|
|
|
||
|
|
[DllImport(libraryName)]
|
||
|
|
private static extern void UggSetLogDelegate(IntPtr callback);
|
||
|
|
|
||
|
|
[DllImport(libraryName)]
|
||
|
|
public static extern int UggTestStartSession(out IntPtr session,
|
||
|
|
IntPtr beginGame,
|
||
|
|
IntPtr advanceFrame,
|
||
|
|
IntPtr loadGameState,
|
||
|
|
IntPtr logGameState,
|
||
|
|
IntPtr saveGameState,
|
||
|
|
IntPtr freeBuffer,
|
||
|
|
IntPtr onEvent,
|
||
|
|
string game, int num_players, int localport);
|
||
|
|
|
||
|
|
[DllImport(libraryName)]
|
||
|
|
private static extern int UggStartSession(out IntPtr session,
|
||
|
|
IntPtr beginGame,
|
||
|
|
IntPtr advanceFrame,
|
||
|
|
IntPtr loadGameState,
|
||
|
|
IntPtr logGameState,
|
||
|
|
IntPtr saveGameState,
|
||
|
|
IntPtr freeBuffer,
|
||
|
|
IntPtr onEvent,
|
||
|
|
string game, int num_players, int localport);
|
||
|
|
|
||
|
|
[DllImport(libraryName)]
|
||
|
|
private static extern int UggStartSpectating(out IntPtr session,
|
||
|
|
IntPtr beginGame,
|
||
|
|
IntPtr advanceFrame,
|
||
|
|
IntPtr loadGameState,
|
||
|
|
IntPtr logGameState,
|
||
|
|
IntPtr saveGameState,
|
||
|
|
IntPtr freeBuffer,
|
||
|
|
IntPtr onEvent,
|
||
|
|
string game, int num_players, int localport, string host_ip, int host_port);
|
||
|
|
|
||
|
|
[DllImport(libraryName)]
|
||
|
|
private static extern int UggSetDisconnectNotifyStart(IntPtr ggpo, int timeout);
|
||
|
|
|
||
|
|
[DllImport(libraryName)]
|
||
|
|
private static extern int UggSetDisconnectTimeout(IntPtr ggpo, int timeout);
|
||
|
|
|
||
|
|
[DllImport(libraryName)]
|
||
|
|
private static extern int UggSynchronizeInput(IntPtr ggpo, IntPtr inputs, int length, out int disconnect_flags);
|
||
|
|
|
||
|
|
[DllImport(libraryName)]
|
||
|
|
private static extern int UggAddLocalInput(IntPtr ggpo, int local_player_handle, long input);
|
||
|
|
|
||
|
|
[DllImport(libraryName)]
|
||
|
|
private static extern int UggCloseSession(IntPtr ggpo);
|
||
|
|
|
||
|
|
[DllImport(libraryName)]
|
||
|
|
private static extern int UggIdle(IntPtr ggpo, int timeout);
|
||
|
|
|
||
|
|
[DllImport(libraryName)]
|
||
|
|
private static extern int UggAddPlayer(IntPtr ggpo, int player_type, int player_num, string player_ip_address, ushort player_port, out int phandle);
|
||
|
|
|
||
|
|
[DllImport(libraryName)]
|
||
|
|
private static extern int UggDisconnectPlayer(IntPtr ggpo, int phandle);
|
||
|
|
|
||
|
|
[DllImport(libraryName)]
|
||
|
|
private static extern int UggSetFrameDelay(IntPtr ggpo, int phandle, int frame_delay);
|
||
|
|
|
||
|
|
[DllImport(libraryName)]
|
||
|
|
private static extern int UggAdvanceFrame(IntPtr ggpo);
|
||
|
|
|
||
|
|
[DllImport(libraryName)]
|
||
|
|
private static extern void UggLog(IntPtr ggpo, string text);
|
||
|
|
|
||
|
|
[DllImport(libraryName)]
|
||
|
|
private static extern int UggGetNetworkStats(IntPtr ggpo, int phandle,
|
||
|
|
out int send_queue_len,
|
||
|
|
out int recv_queue_len,
|
||
|
|
out int ping,
|
||
|
|
out int kbps_sent,
|
||
|
|
out int local_frames_behind,
|
||
|
|
out int remote_frames_behind);
|
||
|
|
|
||
|
|
// Access
|
||
|
|
|
||
|
|
private static IntPtr _logDelegate;
|
||
|
|
|
||
|
|
public static void SetLogDelegate(LogDelegate callback) {
|
||
|
|
_logDelegate = callback != null ? Marshal.GetFunctionPointerForDelegate(callback) : IntPtr.Zero;
|
||
|
|
UggSetLogDelegate(_logDelegate);
|
||
|
|
}
|
||
|
|
|
||
|
|
public static int StartSession(out IntPtr session,
|
||
|
|
IntPtr beginGame,
|
||
|
|
IntPtr advanceFrame,
|
||
|
|
IntPtr loadGameState,
|
||
|
|
IntPtr logGameState,
|
||
|
|
IntPtr saveGameState,
|
||
|
|
IntPtr freeBuffer,
|
||
|
|
IntPtr onEvent,
|
||
|
|
string game, int num_players, int localport) {
|
||
|
|
return UggStartSession(out session, beginGame, advanceFrame, loadGameState, logGameState, saveGameState, freeBuffer, onEvent, game, num_players, localport);
|
||
|
|
}
|
||
|
|
|
||
|
|
public static int StartSpectating(out IntPtr session,
|
||
|
|
IntPtr beginGame,
|
||
|
|
IntPtr advanceFrame,
|
||
|
|
IntPtr loadGameState,
|
||
|
|
IntPtr logGameState,
|
||
|
|
IntPtr saveGameState,
|
||
|
|
IntPtr freeBuffer,
|
||
|
|
IntPtr onEvent,
|
||
|
|
string game, int num_players, int localport, string host_ip, int host_port) {
|
||
|
|
return UggStartSpectating(out session, beginGame, advanceFrame, loadGameState, logGameState, saveGameState, freeBuffer, onEvent, game, num_players, localport, host_ip, host_port);
|
||
|
|
}
|
||
|
|
|
||
|
|
public static int SetDisconnectNotifyStart(IntPtr ggpo, int timeout) {
|
||
|
|
return UggSetDisconnectNotifyStart(ggpo, timeout);
|
||
|
|
}
|
||
|
|
|
||
|
|
public static int SetDisconnectTimeout(IntPtr ggpo, int timeout) {
|
||
|
|
return UggSetDisconnectTimeout(ggpo, timeout);
|
||
|
|
}
|
||
|
|
|
||
|
|
public static long[] SynchronizeInput(IntPtr ggpo, int length, out int disconnect_flags) {
|
||
|
|
IntPtr pnt = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(long)) * length);
|
||
|
|
var result = UggSynchronizeInput(ggpo, pnt, length, out disconnect_flags);
|
||
|
|
var inputs = new long[length];
|
||
|
|
Marshal.Copy(pnt, inputs, 0, length);
|
||
|
|
Marshal.FreeHGlobal(pnt);
|
||
|
|
if (!SUCCEEDED(result)) {
|
||
|
|
throw new Exception(GetErrorCodeMessage(result));
|
||
|
|
}
|
||
|
|
return inputs;
|
||
|
|
}
|
||
|
|
|
||
|
|
public static int AddLocalInput(IntPtr ggpo, int local_player_handle, long input) {
|
||
|
|
return UggAddLocalInput(ggpo, local_player_handle, input);
|
||
|
|
}
|
||
|
|
|
||
|
|
public static int CloseSession(IntPtr ggpo) {
|
||
|
|
return UggCloseSession(ggpo);
|
||
|
|
}
|
||
|
|
|
||
|
|
public static int Idle(IntPtr ggpo, int timeout) {
|
||
|
|
return UggIdle(ggpo, timeout);
|
||
|
|
}
|
||
|
|
|
||
|
|
public static int AddPlayer(IntPtr ggpo, int player_type, int player_num, string player_ip_address, ushort player_port, out int phandle) {
|
||
|
|
return UggAddPlayer(ggpo, player_type, player_num, player_ip_address, player_port, out phandle);
|
||
|
|
}
|
||
|
|
|
||
|
|
public static int DisconnectPlayer(IntPtr ggpo, int phandle) {
|
||
|
|
return UggDisconnectPlayer(ggpo, phandle);
|
||
|
|
}
|
||
|
|
|
||
|
|
public static int SetFrameDelay(IntPtr ggpo, int phandle, int frame_delay) {
|
||
|
|
return UggSetFrameDelay(ggpo, phandle, frame_delay);
|
||
|
|
}
|
||
|
|
|
||
|
|
public static int AdvanceFrame(IntPtr ggpo) {
|
||
|
|
return UggAdvanceFrame(ggpo);
|
||
|
|
}
|
||
|
|
|
||
|
|
public static void Log(IntPtr ggpo, string text) {
|
||
|
|
UggLog(ggpo, text);
|
||
|
|
}
|
||
|
|
|
||
|
|
public static int GetNetworkStats(IntPtr ggpo, int phandle,
|
||
|
|
out int send_queue_len,
|
||
|
|
out int recv_queue_len,
|
||
|
|
out int ping,
|
||
|
|
out int kbps_sent,
|
||
|
|
out int local_frames_behind,
|
||
|
|
out int remote_frames_behind) {
|
||
|
|
return UggGetNetworkStats(ggpo, phandle, out send_queue_len, out recv_queue_len, out ping, out kbps_sent, out local_frames_behind, out remote_frames_behind);
|
||
|
|
}
|
||
|
|
|
||
|
|
public static int TestStartSession(out IntPtr session,
|
||
|
|
IntPtr beginGame,
|
||
|
|
IntPtr advanceFrame,
|
||
|
|
IntPtr loadGameState,
|
||
|
|
IntPtr logGameState,
|
||
|
|
IntPtr saveGameState,
|
||
|
|
IntPtr freeBuffer,
|
||
|
|
IntPtr onEvent,
|
||
|
|
string game, int num_players, int localport) {
|
||
|
|
return UggTestStartSession(out session, beginGame, advanceFrame, loadGameState, logGameState, saveGameState, freeBuffer, onEvent, game, num_players, localport);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|