A game about forced loneliness, made by TACStudios
1using System;
2using System.Runtime.InteropServices;
3using UnityEngine.InputSystem.Utilities;
4
5namespace UnityEngine.InputSystem.LowLevel
6{
7 /// <summary>
8 /// Query the ID and the name of the user paired to the device the command is sent to.
9 /// </summary>
10 /// <remarks>
11 /// This command is only supported on platforms where devices can be paired to user accounts
12 /// at the platform level. Currently this is the case for Xbox and PS4. On Switch, <see
13 /// cref="InitiateUserAccountPairingCommand"/> is supported but the platform does not store
14 /// associations established between devices and users that way.
15 /// </remarks>
16 [StructLayout(LayoutKind.Explicit, Size = kSize)]
17 public unsafe struct QueryPairedUserAccountCommand : IInputDeviceCommandInfo
18 {
19 public static FourCC Type => new FourCC('P', 'A', 'C', 'C');
20
21 internal const int kMaxNameLength = 256;
22 internal const int kMaxIdLength = 256;
23
24 ////REVIEW: is this too heavy to allocate on the stack?
25 internal const int kSize = InputDeviceCommand.kBaseCommandSize + 8 + kMaxNameLength * 2 + kMaxIdLength * 2;
26
27 [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1714:FlagsEnumsShouldHavePluralNames", Justification = "`Result` matches other command result names")]
28 [Flags]
29 public enum Result : long
30 {
31 // Leave bit #0 unused so as to not lead to possible confusion with GenericSuccess.
32
33 /// <summary>
34 /// The device is currently paired to a user account.
35 /// </summary>
36 DevicePairedToUserAccount = 1 << 1,
37
38 /// <summary>
39 /// The system is currently displaying a prompt for the user to select an account to
40 /// use the device with.
41 /// </summary>
42 UserAccountSelectionInProgress = 1 << 2,
43
44 /// <summary>
45 /// User account selection completed.
46 /// </summary>
47 UserAccountSelectionComplete = 1 << 3,
48
49 /// <summary>
50 /// The system had been displaying a prompt
51 /// </summary>
52 UserAccountSelectionCanceled = 1 << 4,
53 }
54
55 [FieldOffset(0)]
56 public InputDeviceCommand baseCommand;
57
58 /// <summary>
59 /// Handle of the user account at the platform level.
60 /// </summary>
61 /// <remarks>
62 /// Note that this is wide enough to store a pointer and does not necessarily need to be a plain integer.
63 /// How the backend determines handles for user accounts is up to the backend.
64 ///
65 /// Be aware that a handle is not guaranteed to be valid beyond the current application run. For stable,
66 /// persistent user account handles,use <see cref="id"/>.
67 /// </remarks>
68 [FieldOffset(InputDeviceCommand.kBaseCommandSize)]
69 public ulong handle;
70
71 [FieldOffset(InputDeviceCommand.kBaseCommandSize + 8)]
72 internal fixed byte nameBuffer[kMaxNameLength * 2];
73
74 [FieldOffset(InputDeviceCommand.kBaseCommandSize + 8 + kMaxNameLength * 2)]
75 internal fixed byte idBuffer[kMaxNameLength * 2];
76
77 /// <summary>
78 /// Persistent ID of the user account the platform level.
79 /// </summary>
80 /// <remarks>
81 /// This ID is guaranteed to not change between application runs, device restarts, and the user
82 /// changing user names on the account.
83 ///
84 /// Use this ID to associate persistent settings with.
85 /// </remarks>
86 public string id
87 {
88 get
89 {
90 fixed(byte* idBufferPtr = idBuffer)
91 return StringHelpers.ReadStringFromBuffer(new IntPtr(idBufferPtr), kMaxIdLength);
92 }
93 set
94 {
95 if (value == null)
96 throw new ArgumentNullException(nameof(value));
97 var length = value.Length;
98 if (length > kMaxIdLength)
99 throw new ArgumentException($"ID '{value}' exceeds maximum supported length of {kMaxIdLength} characters", nameof(value));
100
101 fixed(byte* idBufferPtr = idBuffer)
102 {
103 StringHelpers.WriteStringToBuffer(value, new IntPtr(idBufferPtr), kMaxIdLength);
104 }
105 }
106 }
107
108 /// <summary>
109 /// Name of the user account at the platform level.
110 /// </summary>
111 public string name
112 {
113 get
114 {
115 fixed(byte* nameBufferPtr = nameBuffer)
116 return StringHelpers.ReadStringFromBuffer(new IntPtr(nameBufferPtr), kMaxNameLength);
117 }
118 set
119 {
120 if (value == null)
121 throw new ArgumentNullException("value");
122 var length = value.Length;
123 if (length > kMaxNameLength)
124 throw new ArgumentException($"Name '{value}' exceeds maximum supported length of {kMaxNameLength} characters", nameof(value));
125
126 fixed(byte* nameBufferPtr = nameBuffer)
127 {
128 StringHelpers.WriteStringToBuffer(value, new IntPtr(nameBufferPtr), kMaxNameLength);
129 }
130 }
131 }
132
133 public FourCC typeStatic => Type;
134
135 public static QueryPairedUserAccountCommand Create()
136 {
137 return new QueryPairedUserAccountCommand
138 {
139 baseCommand = new InputDeviceCommand(Type, kSize),
140 };
141 }
142 }
143}