PageRenderTime 49ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 1ms

/SteamKit2/SteamKit2/Util/Utils.cs

https://bitbucket.org/VoiDeD/steamre/
C# | 363 lines | 247 code | 64 blank | 52 comment | 40 complexity | b592d8cd93d03eceb595e881fc22219d MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, Apache-2.0, BSD-3-Clause
  1. /*
  2. * This file is subject to the terms and conditions defined in
  3. * file 'license.txt', which is part of this source code package.
  4. */
  5. using System;
  6. using System.Linq;
  7. using System.Net;
  8. using System.Net.Sockets;
  9. using System.Text;
  10. using Microsoft.Win32;
  11. namespace SteamKit2
  12. {
  13. static class Utils
  14. {
  15. public static DateTime DateTimeFromUnixTime( uint unixTime )
  16. {
  17. DateTime origin = new DateTime( 1970, 1, 1, 0, 0, 0, 0 );
  18. return origin.AddSeconds( unixTime );
  19. }
  20. public static uint DateTimeToUnixTime( DateTime time )
  21. {
  22. DateTime origin = new DateTime( 1970, 1, 1, 0, 0, 0, 0 );
  23. return ( uint )( time - origin ).TotalSeconds;
  24. }
  25. public static string EncodeHexString(byte[] input)
  26. {
  27. return input.Aggregate(new StringBuilder(),
  28. (sb, v) => sb.Append(v.ToString("x2"))
  29. ).ToString();
  30. }
  31. public static byte[] DecodeHexString(string hex)
  32. {
  33. if (hex == null)
  34. return null;
  35. int chars = hex.Length;
  36. byte[] bytes = new byte[chars / 2];
  37. for (int i = 0; i < chars; i += 2)
  38. bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
  39. return bytes;
  40. }
  41. public static EOSType GetOSType()
  42. {
  43. var osVer = Environment.OSVersion;
  44. var ver = osVer.Version;
  45. switch ( osVer.Platform )
  46. {
  47. case PlatformID.Win32Windows:
  48. {
  49. switch ( ver.Minor )
  50. {
  51. case 0:
  52. return EOSType.Win95;
  53. case 10:
  54. return EOSType.Win98;
  55. case 90:
  56. return EOSType.WinME;
  57. default:
  58. return EOSType.WinUnknown;
  59. }
  60. }
  61. case PlatformID.Win32NT:
  62. {
  63. switch ( ver.Major )
  64. {
  65. case 4:
  66. return EOSType.WinNT;
  67. case 5: // XP family
  68. if ( ver.Minor == 0 )
  69. return EOSType.Win200;
  70. if ( ver.Minor == 1 || ver.Minor == 2 )
  71. return EOSType.WinXP;
  72. goto default;
  73. case 6: // Vista & 7
  74. if ( ver.Minor == 0 )
  75. return EOSType.WinVista;
  76. if ( ver.Minor == 1 )
  77. return EOSType.Win7;
  78. goto default;
  79. default:
  80. return EOSType.WinUnknown;
  81. }
  82. }
  83. case PlatformID.Unix:
  84. return EOSType.LinuxUnknown; // this _could_ be mac, but we're gonna just go with linux for now
  85. default:
  86. return EOSType.Unknown;
  87. }
  88. }
  89. public static byte[] GenerateMachineID()
  90. {
  91. // this is steamkit's own implementation, it doesn't match what steamclient does
  92. // but this should make it so individual systems can be identified
  93. PlatformID platform = Environment.OSVersion.Platform;
  94. if ( platform == PlatformID.Win32NT )
  95. {
  96. string hwString = "foobar";
  97. try
  98. {
  99. RegistryKey localKey = RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, RegistryView.Registry64);
  100. localKey = localKey.OpenSubKey(@"SOFTWARE\Microsoft\Cryptography");
  101. if (localKey != null)
  102. {
  103. hwString = localKey.GetValue("MachineGuid").ToString();
  104. }
  105. }
  106. catch { }
  107. try
  108. {
  109. return CryptoHelper.SHAHash( Encoding.ASCII.GetBytes( hwString.ToString() ) );
  110. }
  111. catch { return null; }
  112. }
  113. else
  114. {
  115. // todo: implement me!
  116. return null;
  117. }
  118. }
  119. public static T[] GetAttributes<T>( this Type type, bool inherit = false )
  120. where T : Attribute
  121. {
  122. return type.GetCustomAttributes( typeof( T ), inherit ) as T[];
  123. }
  124. }
  125. /// <summary>
  126. /// Contains various utility functions for handling EMsgs.
  127. /// </summary>
  128. public static class MsgUtil
  129. {
  130. private const uint ProtoMask = 0x80000000;
  131. private const uint EMsgMask = ~ProtoMask;
  132. /// <summary>
  133. /// Strips off the protobuf message flag and returns an EMsg.
  134. /// </summary>
  135. /// <param name="msg">The message number.</param>
  136. /// <returns>The underlying EMsg.</returns>
  137. public static EMsg GetMsg( uint msg )
  138. {
  139. return ( EMsg )( msg & EMsgMask );
  140. }
  141. /// <summary>
  142. /// Strips off the protobuf message flag and returns an EMsg.
  143. /// </summary>
  144. /// <param name="msg">The message number.</param>
  145. /// <returns>The underlying EMsg.</returns>
  146. public static uint GetGCMsg( uint msg )
  147. {
  148. return ( msg & EMsgMask );
  149. }
  150. /// <summary>
  151. /// Strips off the protobuf message flag and returns an EMsg.
  152. /// </summary>
  153. /// <param name="msg">The message number.</param>
  154. /// <returns>The underlying EMsg.</returns>
  155. public static EMsg GetMsg( EMsg msg )
  156. {
  157. return GetMsg( ( uint )msg );
  158. }
  159. /// <summary>
  160. /// Determines whether message is protobuf flagged.
  161. /// </summary>
  162. /// <param name="msg">The message.</param>
  163. /// <returns>
  164. /// <c>true</c> if this message is protobuf flagged; otherwise, <c>false</c>.
  165. /// </returns>
  166. public static bool IsProtoBuf( uint msg )
  167. {
  168. return ( msg & ProtoMask ) > 0;
  169. }
  170. /// <summary>
  171. /// Determines whether message is protobuf flagged.
  172. /// </summary>
  173. /// <param name="msg">The message.</param>
  174. /// <returns>
  175. /// <c>true</c> if this message is protobuf flagged; otherwise, <c>false</c>.
  176. /// </returns>
  177. public static bool IsProtoBuf( EMsg msg )
  178. {
  179. return IsProtoBuf( ( uint )msg );
  180. }
  181. /// <summary>
  182. /// Crafts an EMsg, flagging it if required.
  183. /// </summary>
  184. /// <param name="msg">The EMsg to flag.</param>
  185. /// <param name="protobuf">if set to <c>true</c>, the message is protobuf flagged.</param>
  186. /// <returns>A crafted EMsg, flagged if requested.</returns>
  187. public static EMsg MakeMsg( EMsg msg, bool protobuf = false )
  188. {
  189. if ( protobuf )
  190. return ( EMsg )( ( uint )msg | ProtoMask );
  191. return msg;
  192. }
  193. /// <summary>
  194. /// Crafts an EMsg, flagging it if required.
  195. /// </summary>
  196. /// <param name="msg">The EMsg to flag.</param>
  197. /// <param name="protobuf">if set to <c>true</c>, the message is protobuf flagged.</param>
  198. /// <returns>A crafted EMsg, flagged if requested.</returns>
  199. public static uint MakeGCMsg( uint msg, bool protobuf = false )
  200. {
  201. if ( protobuf )
  202. return msg | ProtoMask;
  203. return msg;
  204. }
  205. }
  206. static class WebHelpers
  207. {
  208. static bool IsUrlSafeChar( char ch )
  209. {
  210. if ( ( ( ( ch >= 'a' ) && ( ch <= 'z' ) ) || ( ( ch >= 'A' ) && ( ch <= 'Z' ) ) ) || ( ( ch >= '0' ) && ( ch <= '9' ) ) )
  211. {
  212. return true;
  213. }
  214. switch ( ch )
  215. {
  216. case '-':
  217. case '.':
  218. case '_':
  219. return true;
  220. }
  221. return false;
  222. }
  223. public static string UrlEncode( string input )
  224. {
  225. return UrlEncode( Encoding.UTF8.GetBytes( input ) );
  226. }
  227. public static string UrlEncode( byte[] input )
  228. {
  229. StringBuilder encoded = new StringBuilder( input.Length * 2 );
  230. for ( int i = 0 ; i < input.Length ; i++ )
  231. {
  232. char inch = ( char )input[ i ];
  233. if ( IsUrlSafeChar( inch ) )
  234. {
  235. encoded.Append( inch );
  236. }
  237. else if ( inch == ' ' )
  238. {
  239. encoded.Append( '+' );
  240. }
  241. else
  242. {
  243. encoded.AppendFormat( "%{0:X2}", input[ i ] );
  244. }
  245. }
  246. return encoded.ToString();
  247. }
  248. }
  249. static class NetHelpers
  250. {
  251. public static IPAddress GetLocalIP(Socket activeSocket)
  252. {
  253. IPEndPoint ipEndPoint = activeSocket.LocalEndPoint as IPEndPoint;
  254. if ( ipEndPoint == null || ipEndPoint.Address == IPAddress.Any )
  255. throw new Exception( "Socket not connected" );
  256. return ipEndPoint.Address;
  257. }
  258. public static IPAddress GetIPAddress( uint ipAddr )
  259. {
  260. byte[] addrBytes = BitConverter.GetBytes( ipAddr );
  261. Array.Reverse( addrBytes );
  262. return new IPAddress( addrBytes );
  263. }
  264. public static uint GetIPAddress( IPAddress ipAddr )
  265. {
  266. byte[] addrBytes = ipAddr.GetAddressBytes();
  267. Array.Reverse( addrBytes );
  268. return BitConverter.ToUInt32( addrBytes, 0 );
  269. }
  270. public static uint EndianSwap( uint input )
  271. {
  272. return ( uint )IPAddress.NetworkToHostOrder( ( int )input );
  273. }
  274. public static ulong EndianSwap( ulong input )
  275. {
  276. return ( ulong )IPAddress.NetworkToHostOrder( ( long )input );
  277. }
  278. public static ushort EndianSwap( ushort input )
  279. {
  280. return ( ushort )IPAddress.NetworkToHostOrder( ( short )input );
  281. }
  282. }
  283. class TimeoutableWebClient : WebClient
  284. {
  285. public int Timeout { get; set; }
  286. public TimeoutableWebClient()
  287. {
  288. // msdn docs state that the default timeout of a HttpWebRequest is 100,000 milliseconds (100 sec)
  289. Timeout = 100000;
  290. }
  291. protected override WebRequest GetWebRequest( Uri address )
  292. {
  293. var webReq = base.GetWebRequest( address );
  294. if ( webReq != null )
  295. webReq.Timeout = Timeout;
  296. return webReq;
  297. }
  298. }
  299. }