CnC_Remastered_Collection

Command and Conquer: Red Alert
Log | Files | Refs | README | LICENSE

InteropHelp.cs (7747B)


      1 // This file is provided under The MIT License as part of Steamworks.NET.
      2 // Copyright (c) 2013-2019 Riley Labrecque
      3 // Please see the included LICENSE.txt for additional information.
      4 
      5 // This file is automatically generated.
      6 // Changes to this file will be reverted when you update Steamworks.NET
      7 
      8 #if UNITY_ANDROID || UNITY_IOS || UNITY_TIZEN || UNITY_TVOS || UNITY_WEBGL || UNITY_WSA || UNITY_PS4 || UNITY_WII || UNITY_XBOXONE || UNITY_SWITCH
      9 #define DISABLESTEAMWORKS
     10 #endif
     11 
     12 #if !DISABLESTEAMWORKS
     13 
     14 using System.Runtime.InteropServices;
     15 using IntPtr = System.IntPtr;
     16 
     17 using System.Text;
     18 
     19 namespace Steamworks {
     20 	public class InteropHelp {
     21 		public static void TestIfPlatformSupported() {
     22 #if !UNITY_EDITOR && !UNITY_STANDALONE && !STEAMWORKS_WIN && !STEAMWORKS_LIN_OSX
     23 			throw new System.InvalidOperationException("Steamworks functions can only be called on platforms that Steam is available on.");
     24 #endif
     25 		}
     26 
     27 		public static void TestIfAvailableClient() {
     28 			TestIfPlatformSupported();
     29 			if (CSteamAPIContext.GetSteamClient() == System.IntPtr.Zero) {
     30 				if (!CSteamAPIContext.Init()) {
     31 					throw new System.InvalidOperationException("Steamworks is not initialized.");
     32 				}
     33 			}
     34 		}
     35 
     36 		public static void TestIfAvailableGameServer() {
     37 			TestIfPlatformSupported();
     38 			if (CSteamGameServerAPIContext.GetSteamClient() == System.IntPtr.Zero) {
     39 				if (!CSteamGameServerAPIContext.Init()) {
     40 					throw new System.InvalidOperationException("Steamworks GameServer is not initialized.");
     41 				}
     42 			}
     43 		}
     44 
     45 		// This continues to exist for both 'out string' and strings returned by Steamworks functions.
     46 		public static string PtrToStringUTF8(IntPtr nativeUtf8) {
     47 			if (nativeUtf8 == IntPtr.Zero) {
     48 				return null;
     49 			}
     50 
     51 			int len = 0;
     52 
     53 			while (Marshal.ReadByte(nativeUtf8, len) != 0) {
     54 				++len;
     55 			}
     56 
     57 			if (len == 0) {
     58 				return string.Empty;
     59 			}
     60 
     61 			byte[] buffer = new byte[len];
     62 			Marshal.Copy(nativeUtf8, buffer, 0, buffer.Length);
     63 			return Encoding.UTF8.GetString(buffer);
     64 		}
     65 
     66 		// This is for 'const char *' arguments which we need to ensure do not get GC'd while Steam is using them.
     67 		// We can't use an ICustomMarshaler because Unity crashes when a string between 96 and 127 characters long is defined/initialized at the top of class scope...
     68 #if UNITY_EDITOR || UNITY_STANDALONE || STEAMWORKS_WIN || STEAMWORKS_LIN_OSX
     69 		public class UTF8StringHandle : Microsoft.Win32.SafeHandles.SafeHandleZeroOrMinusOneIsInvalid {
     70 			public UTF8StringHandle(string str)
     71 				: base(true) {
     72 				if (str == null) {
     73 					SetHandle(IntPtr.Zero);
     74 					return;
     75 				}
     76 
     77 				// +1 for '\0'
     78 				byte[] strbuf = new byte[Encoding.UTF8.GetByteCount(str) + 1];
     79 				Encoding.UTF8.GetBytes(str, 0, str.Length, strbuf, 0);
     80 				IntPtr buffer = Marshal.AllocHGlobal(strbuf.Length);
     81 				Marshal.Copy(strbuf, 0, buffer, strbuf.Length);
     82 
     83 				SetHandle(buffer);
     84 			}
     85 
     86 			protected override bool ReleaseHandle() {
     87 				if (!IsInvalid) {
     88 					Marshal.FreeHGlobal(handle);
     89 				}
     90 				return true;
     91 			}
     92 		}
     93 #else
     94 		public class UTF8StringHandle : IDisposable {
     95 			public UTF8StringHandle(string str) { }
     96 			public void Dispose() {}
     97 		}
     98 #endif
     99 
    100 		// TODO - Should be IDisposable
    101 		// We can't use an ICustomMarshaler because Unity dies when MarshalManagedToNative() gets called with a generic type.
    102 		public class SteamParamStringArray {
    103 			// The pointer to each AllocHGlobal() string
    104 			IntPtr[] m_Strings;
    105 			// The pointer to the condensed version of m_Strings
    106 			IntPtr m_ptrStrings;
    107 			// The pointer to the StructureToPtr version of SteamParamStringArray_t that will get marshaled
    108 			IntPtr m_pSteamParamStringArray;
    109 
    110 			public SteamParamStringArray(System.Collections.Generic.IList<string> strings) {
    111 				if (strings == null) {
    112 					m_pSteamParamStringArray = IntPtr.Zero;
    113 					return;
    114 				}
    115 
    116 				m_Strings = new IntPtr[strings.Count];
    117 				for (int i = 0; i < strings.Count; ++i) {
    118 					byte[] strbuf = new byte[Encoding.UTF8.GetByteCount(strings[i]) + 1];
    119 					Encoding.UTF8.GetBytes(strings[i], 0, strings[i].Length, strbuf, 0);
    120 					m_Strings[i] = Marshal.AllocHGlobal(strbuf.Length);
    121 					Marshal.Copy(strbuf, 0, m_Strings[i], strbuf.Length);
    122 				}
    123 
    124 				m_ptrStrings = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr)) * m_Strings.Length);
    125 				SteamParamStringArray_t stringArray = new SteamParamStringArray_t() {
    126 					m_ppStrings = m_ptrStrings,
    127 					m_nNumStrings = m_Strings.Length
    128 				};
    129 				Marshal.Copy(m_Strings, 0, stringArray.m_ppStrings, m_Strings.Length);
    130 
    131 				m_pSteamParamStringArray = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SteamParamStringArray_t)));
    132 				Marshal.StructureToPtr(stringArray, m_pSteamParamStringArray, false);
    133 			}
    134 
    135 			~SteamParamStringArray() {
    136 				foreach (IntPtr ptr in m_Strings) {
    137 					Marshal.FreeHGlobal(ptr);
    138 				}
    139 
    140 				if (m_ptrStrings != IntPtr.Zero) {
    141 					Marshal.FreeHGlobal(m_ptrStrings);
    142 				}
    143 
    144 				if (m_pSteamParamStringArray != IntPtr.Zero) {
    145 					Marshal.FreeHGlobal(m_pSteamParamStringArray);
    146 				}
    147 			}
    148 
    149 			public static implicit operator IntPtr(SteamParamStringArray that) {
    150 				return that.m_pSteamParamStringArray;
    151 			}
    152 		}
    153 	}
    154 
    155 	// TODO - Should be IDisposable
    156 	// MatchMaking Key-Value Pair Marshaller
    157 	public class MMKVPMarshaller {
    158 		private IntPtr m_pNativeArray;
    159 		private IntPtr m_pArrayEntries;
    160 
    161 		public MMKVPMarshaller(MatchMakingKeyValuePair_t[] filters) {
    162 			if (filters == null) {
    163 				return;
    164 			}
    165 
    166 			int sizeOfMMKVP = Marshal.SizeOf(typeof(MatchMakingKeyValuePair_t));
    167 
    168 			m_pNativeArray = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr)) * filters.Length);
    169 			m_pArrayEntries = Marshal.AllocHGlobal(sizeOfMMKVP * filters.Length);
    170 			for (int i = 0; i < filters.Length; ++i) {
    171 				Marshal.StructureToPtr(filters[i], new IntPtr(m_pArrayEntries.ToInt64() + (i * sizeOfMMKVP)), false);
    172 			}
    173 
    174 			Marshal.WriteIntPtr(m_pNativeArray, m_pArrayEntries);
    175 		}
    176 
    177 		~MMKVPMarshaller() {
    178 			if (m_pArrayEntries != IntPtr.Zero) {
    179 				Marshal.FreeHGlobal(m_pArrayEntries);
    180 			}
    181 			if (m_pNativeArray != IntPtr.Zero) {
    182 				Marshal.FreeHGlobal(m_pNativeArray);
    183 			}
    184 		}
    185 
    186 		public static implicit operator IntPtr(MMKVPMarshaller that) {
    187 			return that.m_pNativeArray;
    188 		}
    189 	}
    190 
    191 	public class DllCheck {
    192 #if DISABLED
    193 		[DllImport("kernel32.dll")]
    194 		public static extern IntPtr GetModuleHandle(string lpModuleName);
    195 
    196 		[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
    197 		extern static int GetModuleFileName(IntPtr hModule, StringBuilder strFullPath, int nSize);
    198 #endif
    199 
    200 		/// <summary>
    201 		/// This is an optional runtime check to ensure that the dlls are the correct version. Returns false only if the steam_api.dll is found and it's the wrong size or version number.
    202 		/// </summary>
    203 		public static bool Test() {
    204 #if DISABLED
    205 			bool ret = CheckSteamAPIDLL();
    206 #endif
    207 			return true;
    208 		}
    209 
    210 #if DISABLED
    211 		private static bool CheckSteamAPIDLL() {
    212 			string fileName;
    213 			int fileBytes;
    214 			if (IntPtr.Size == 4) {
    215 				fileName = "steam_api.dll";
    216 				fileBytes = Version.SteamAPIDLLSize;
    217 			}
    218 			else {
    219 				fileName = "steam_api64.dll";
    220 				fileBytes = Version.SteamAPI64DLLSize;
    221 			}
    222 
    223 			IntPtr handle = GetModuleHandle(fileName);
    224 			if (handle == IntPtr.Zero) {
    225 				return true;
    226 			}
    227 
    228 			StringBuilder filePath = new StringBuilder(256);
    229 			GetModuleFileName(handle, filePath, filePath.Capacity);
    230 			string file = filePath.ToString();
    231 
    232 			// If we can not find the file we'll just skip it and let the DllNotFoundException take care of it.
    233 			if (System.IO.File.Exists(file)) {
    234 				System.IO.FileInfo fInfo = new System.IO.FileInfo(file);
    235 				if (fInfo.Length != fileBytes) {
    236 					return false;
    237 				}
    238 
    239 				if (System.Diagnostics.FileVersionInfo.GetVersionInfo(file).FileVersion != Version.SteamAPIDLLVersion) {
    240 					return false;
    241 				}
    242 			}
    243 			return true;
    244 		}
    245 #endif
    246 	}
    247 }
    248 
    249 #endif // !DISABLESTEAMWORKS