Barotrauma Client Doc
SteamId.cs
1 #nullable enable
2 using System;
3 
4 namespace Barotrauma.Networking
5 {
6  sealed class SteamId : AccountId
7  {
8  public readonly UInt64 Value;
9 
10  public override string StringRepresentation { get; }
11 
38 
39  private const string steam64Prefix = "STEAM64_";
40  private const string steam40Prefix = "STEAM_";
41 
42  private const UInt64 usualAccountInstance = 1;
43  private const UInt64 usualAccountType = 1;
44 
45  static UInt64 ExtractBits(UInt64 id, int offset, int numberOfBits)
46  => (id >> offset) & ((1ul << numberOfBits) - 1ul);
47 
48  static UInt64 ExtractY(UInt64 id)
49  => ExtractBits(id, offset: 0, numberOfBits: 1);
50  static UInt64 ExtractAccountNumberRemainder(UInt64 id)
51  => ExtractBits(id, offset: 1, numberOfBits: 31);
52  static UInt64 ExtractAccountInstance(UInt64 id)
53  => ExtractBits(id, offset: 32, numberOfBits: 20);
54  static UInt64 ExtractAccountType(UInt64 id)
55  => ExtractBits(id, offset: 52, numberOfBits: 4);
56  static UInt64 ExtractUniverse(UInt64 id)
57  => ExtractBits(id, offset: 56, numberOfBits: 8);
58 
59  public SteamId(UInt64 value)
60  {
61  Value = value;
62 
63  if (ExtractAccountInstance(Value) == usualAccountInstance
64  && ExtractAccountType(Value) == usualAccountType)
65  {
66  UInt64 y = ExtractY(Value);
67  UInt64 accountNumberRemainder = ExtractAccountNumberRemainder(Value);
68  UInt64 universe = ExtractUniverse(Value);
69  StringRepresentation = $"{steam40Prefix}{universe}:{y}:{accountNumberRemainder}";
70  }
71  else
72  {
73  StringRepresentation = $"{steam64Prefix}{Value}";
74  }
75  }
76 
77  public override string ToString() => StringRepresentation;
78 
79  public new static Option<SteamId> Parse(string str)
80  {
81  if (str.IsNullOrWhiteSpace()) { return Option<SteamId>.None(); }
82 
83  if (str.StartsWith(steam64Prefix, StringComparison.InvariantCultureIgnoreCase)) { str = str[steam64Prefix.Length..]; }
84  if (UInt64.TryParse(str, out UInt64 retVal) && ExtractAccountInstance(retVal) > 0)
85  {
86  return Option<SteamId>.Some(new SteamId(retVal));
87  }
88 
89  if (!str.StartsWith(steam40Prefix, StringComparison.InvariantCultureIgnoreCase)) { return Option<SteamId>.None(); }
90  string[] split = str[steam40Prefix.Length..].Split(':');
91  if (split.Length != 3) { return Option<SteamId>.None(); }
92 
93  if (!UInt64.TryParse(split[0], out UInt64 universe)) { return Option<SteamId>.None(); }
94  if (!UInt64.TryParse(split[1], out UInt64 y)) { return Option<SteamId>.None(); }
95  if (!UInt64.TryParse(split[2], out UInt64 accountNumber)) { return Option<SteamId>.None(); }
96 
97  return Option<SteamId>.Some(
98  new SteamId((universe << 56)
99  | usualAccountType << 52
100  | usualAccountInstance << 32
101  | (accountNumber << 1)
102  | y));
103  }
104 
105  public override bool Equals(object? obj)
106  => obj switch
107  {
108  SteamId otherId => this == otherId,
109  _ => false
110  };
111 
112  public override int GetHashCode()
113  => Value.GetHashCode();
114 
115  public static bool operator ==(SteamId a, SteamId b)
116  => a.Value == b.Value;
117 
118  public static bool operator !=(SteamId a, SteamId b)
119  => !(a == b);
120  }
121 }
static bool operator==(SteamId a, SteamId b)
static new Option< SteamId > Parse(string str)
Definition: SteamId.cs:79
override string ToString()
readonly UInt64 Value
Definition: SteamId.cs:8
static bool operator!=(SteamId a, SteamId b)
override bool Equals(object? obj)
override string StringRepresentation
Definition: SteamId.cs:10
static Option< T > Some(T value)
static UnspecifiedNone None
Definition: Option.cs:119