ReceivedData;
108 | uint32 Size;
109 |
110 | while(ConnectionSocket->HasPendingData(Size))
111 | {
112 | ReceivedData.Init(0, FMath::Min(Size, 65507u));
113 | int32 ReadData = 0;
114 | ConnectionSocket->Recv(ReceivedData.GetData(), ReceivedData.Num(), ReadData);
115 | }
116 |
117 | ReceivedData.Add(0);
118 | const FString Request = UTF8_TO_TCHAR(ReceivedData.GetData());
119 | if(!Request.IsEmpty())
120 | RetrieveAuthKey(Request);
121 |
122 | const FString Response = TEXT("HTTP/1.1 200 OK\r\n\
123 | Cache-Control: no-cache, private\n\r\
124 | Server: Unreal-Socket-Server\n\r\n\r\
125 | \r\n\r\nSuccess!\
126 | \r\n\rSuccess!
\nYou can close this window now!
");
127 |
128 | const TCHAR* ResponseData = *Response;
129 | const int32 ResponseSize = FCString::Strlen(ResponseData);
130 | int32 ResponseSent = 0;
131 | ConnectionSocket->Send((uint8*)TCHAR_TO_UTF8(ResponseData), ResponseSize, ResponseSent);
132 | ConnectionSocket->Shutdown(ESocketShutdownMode::ReadWrite);
133 | bListening = false;
134 | }
135 |
136 | void USpotifyService::RetrieveAuthKey(FString HttpResponse)
137 | {
138 | const FRegexPattern AuthCodeRegex(TEXT("/?code=([\\d\\w-_]+)"));
139 | const FRegexPattern ErrorCodeRegex(TEXT("/?error=([\\d\\w-_]+)"));
140 | FRegexMatcher AuthMatcher(AuthCodeRegex, HttpResponse);
141 | FRegexMatcher ErrorMatcher(ErrorCodeRegex, HttpResponse);
142 | if(AuthMatcher.FindNext())
143 | {
144 | AuthKey = AuthMatcher.GetCaptureGroup(1);
145 | bListening = false;
146 | ServerSocket->Close();
147 | RequestRefreshKey();
148 | }
149 | if(ErrorMatcher.FindNext())
150 | {
151 | UE_LOG(LogSpotify, Error, TEXT("Error Authenticating with Spotify: %s"), *ErrorMatcher.GetCaptureGroup(1));
152 | }
153 |
154 | }
155 |
156 | void USpotifyService::RefreshAccessKey()
157 | {
158 | if(RefreshKey.IsEmpty() || ClientKey.IsEmpty()) return;
159 |
160 | UE_LOG(LogSpotify, Verbose, TEXT("Requesting new Access Key."));
161 |
162 | auto Request = Http->CreateRequest();
163 | Request->SetURL("https://accounts.spotify.com/api/token");
164 | Request->SetVerb("POST");
165 | Request->SetHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
166 | Request->SetContentAsString(FString::Printf(TEXT("grant_type=refresh_token&refresh_token=%s&client_id=%s"), *RefreshKey, *ClientKey));
167 | Request->OnProcessRequestComplete().BindUObject(this, &USpotifyService::ReceiveRefreshKey);
168 | Request->ProcessRequest();
169 | }
170 |
171 | void USpotifyService::RequestRefreshKey()
172 | {
173 | if(!Http) return;
174 |
175 | auto Request = Http->CreateRequest();
176 | Request->SetURL("https://accounts.spotify.com/api/token");
177 | Request->SetVerb("POST");
178 | const FString Body = FString::Printf(TEXT("grant_type=authorization_code&code=%s&redirect_uri=%s&client_id=%s&code_verifier=%s"),
179 | *AuthKey, *RedirectURL, *ClientKey, *Verify);
180 | Request->SetContentAsString(Body);
181 | Request->SetHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
182 | Request->OnProcessRequestComplete().BindUObject(this, &USpotifyService::ReceiveRefreshKey);
183 | Request->ProcessRequest();
184 | }
185 |
186 | void USpotifyService::RequestPlaybackInformation()
187 | {
188 | if(!Http || AccessKey.IsEmpty()) return;
189 |
190 | auto Request = Http->CreateRequest();
191 | Request->SetURL("https://api.spotify.com/v1/me/player?market=from_token");
192 | Request->SetVerb("GET");
193 | Request->SetHeader("Authorization", FString::Printf(TEXT("Bearer %s"), *AccessKey));
194 | Request->OnProcessRequestComplete().BindUObject(this, &USpotifyService::ReceivePlaybackInformation);
195 | Request->ProcessRequest();
196 | UE_LOG(LogSpotify, Verbose, TEXT("Requesting Playback Info."));
197 | }
198 |
199 | void USpotifyService::PlaybackRequest(const FString& Url, const FString& Verb)
200 | {
201 | if(!Http || AccessKey.IsEmpty()) return;
202 |
203 | auto Request = Http->CreateRequest();
204 | Request->SetURL(Url);
205 | Request->SetVerb(Verb);
206 | Request->SetHeader("Authorization", FString::Printf(TEXT("Bearer %s"), *AccessKey));
207 | Request->OnProcessRequestComplete().BindUObject(this, &USpotifyService::ReceivePlay);
208 | Request->ProcessRequest();
209 | }
210 |
211 | void USpotifyService::PlaybackRequest(const FString& Url, const FString& Verb, const FString& Body)
212 | {
213 | if(!Http || AccessKey.IsEmpty()) return;
214 |
215 | auto Request = Http->CreateRequest();
216 | Request->SetURL(Url);
217 | Request->SetVerb(Verb);
218 | Request->SetHeader("Authorization", FString::Printf(TEXT("Bearer %s"), *AccessKey));
219 | Request->SetContentAsString(Body);
220 | Request->OnProcessRequestComplete().BindUObject(this, &USpotifyService::ReceivePlay);
221 | Request->ProcessRequest();
222 | }
223 |
224 | void USpotifyService::RequestPlay()
225 | {
226 | PlaybackRequest("https://api.spotify.com/v1/me/player/play", "PUT");
227 | UE_LOG(LogSpotify, Verbose, TEXT("Requesting Resume Playback."));
228 | }
229 |
230 | void USpotifyService::RequestPause()
231 | {
232 | PlaybackRequest("https://api.spotify.com/v1/me/player/pause", "PUT");
233 | UE_LOG(LogSpotify, Verbose, TEXT("Requesting Pause Playback."));
234 | }
235 |
236 | void USpotifyService::RequestNext()
237 | {
238 | PlaybackRequest("https://api.spotify.com/v1/me/player/next", "POST");
239 | UE_LOG(LogSpotify, Verbose, TEXT("Requesting Next Song."));
240 | }
241 |
242 | void USpotifyService::RequestPrev()
243 | {
244 | PlaybackRequest("https://api.spotify.com/v1/me/player/previous", "POST");
245 | UE_LOG(LogSpotify, Verbose, TEXT("Requesting Previous Song."));
246 | }
247 |
248 | void USpotifyService::Seek(int TimeInSeconds)
249 | {
250 | const int TimeInMS = TimeInSeconds * 1000;
251 | PlaybackRequest("https://api.spotify.com/v1/me/player/previous", "PUT", FString::Printf(TEXT("position_ms=%d"), TimeInMS));
252 | UE_LOG(LogSpotify, Verbose, TEXT("Requesting Seek."));
253 | }
254 |
255 | void USpotifyService::SetVolume(float Val)
256 | {
257 | const int VolPercent = FMath::Clamp(Val * 100, 0, 100);
258 | PlaybackRequest(FString::Printf(TEXT("https://api.spotify.com/v1/me/player/volume?volume_percent=%d"), VolPercent), "PUT");
259 | UE_LOG(LogSpotify, Verbose, TEXT("Requesting Volume."));
260 | }
261 |
262 | void USpotifyService::ReceiveRefreshKey(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful)
263 | {
264 | if(!bWasSuccessful) return;
265 |
266 | if( Response->GetResponseCode() >= 200 && Response->GetResponseCode() < 300)
267 | {
268 | const TSharedRef> JsonReader = TJsonReaderFactory<>::Create(Response->GetContentAsString());
269 |
270 | TSharedPtr ParsedResponse;
271 | if(FJsonSerializer::Deserialize(JsonReader, ParsedResponse))
272 | {
273 | const int Expires = ParsedResponse->GetIntegerField("expires_in");
274 | AccessKeyExpiration = FDateTime::Now() + FTimespan(0, 0, Expires);
275 | AccessKey = ParsedResponse->GetStringField("access_token");
276 | RefreshKey = ParsedResponse->GetStringField("refresh_token");
277 | // Resfresh Access Key 50 Seconds before it expires.
278 | GetWorld()->GetTimerManager().ClearTimer(AccessKeyExpireTimerHandle);
279 | GetWorld()->GetTimerManager().ClearTimer(PlaybackInfoTimerHandle);
280 | GetWorld()->GetTimerManager().SetTimer(AccessKeyExpireTimerHandle, this, &USpotifyService::RefreshAccessKey, Expires - 50, false);
281 | GetWorld()->GetTimerManager().SetTimer(PlaybackInfoTimerHandle, this, &USpotifyService::RequestPlaybackInformation, 1, true);
282 | }
283 |
284 | return;
285 | }
286 | UE_LOG(LogSpotify, Error, TEXT("RES: %s"), *Response->GetContentAsString());
287 | }
288 |
289 |
290 | void USpotifyService::ReceivePlaybackInformation(FHttpRequestPtr Request, FHttpResponsePtr Response,
291 | bool bWasSuccessful)
292 | {
293 | if(!bWasSuccessful) return;
294 | if(Response->GetResponseCode() == 200)
295 | {
296 | const TSharedRef> JsonReader = TJsonReaderFactory<>::Create(Response->GetContentAsString());
297 | TSharedPtr ParsedResponse;
298 | if(FJsonSerializer::Deserialize(JsonReader, ParsedResponse))
299 | {
300 |
301 | const int Progress = ParsedResponse->GetIntegerField("progress_ms");
302 | const bool Playing = ParsedResponse->GetBoolField("is_playing");
303 |
304 |
305 | const TSharedPtr Device = ParsedResponse->GetObjectField("device");
306 | const TSharedPtr Item = ParsedResponse->GetObjectField("item");
307 | const TArray> Artists = Item->GetArrayField("artists");
308 | const TSharedPtr Album = Item->GetObjectField("album");
309 |
310 | const int Volume = Device->GetIntegerField("volume_percent");
311 | const int Duration = Item->GetIntegerField("duration_ms");
312 | const FString SongName = Item->GetStringField("name");
313 | const FString AlbumName = Album->GetStringField("name");
314 | TArray ArtistNames;
315 | for(const auto& Artist : Artists)
316 | {
317 | ArtistNames.Add( Artist->AsObject()->GetStringField("name"));
318 | }
319 |
320 | if(SongId == Item->GetStringField("id"))
321 | {
322 | OnPlaybackAdvancedDelegate.Broadcast(Duration, Progress);
323 | return;
324 | }
325 | SongId = Item->GetStringField("id");
326 | OnReceivePlaybackDataDelegate.Broadcast(SongName, ArtistNames, AlbumName, Volume, Duration, Progress, Playing);
327 |
328 | }
329 | }
330 | if(Response->GetResponseCode() == 204)
331 | {
332 | UE_LOG(LogSpotify, Verbose, TEXT("Received Playback, no device playing or in private session."));
333 | }
334 | }
335 |
336 | void USpotifyService::ReceivePlay(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful)
337 | {
338 | if(!bWasSuccessful) return;
339 | if(Response->GetResponseCode() == 204)
340 | {
341 | UE_LOG(LogSpotify, Verbose, TEXT("Request Successful."));
342 | }
343 | else if(Response->GetResponseCode() == 404)
344 | {
345 | UE_LOG(LogSpotify, Error, TEXT("Device not Found"));
346 | }
347 | else if(Response->GetResponseCode() == 403)
348 | {
349 | UE_LOG(LogSpotify, Error, TEXT("User is Non-Premium"));
350 | }
351 | else
352 | {
353 | UE_LOG(LogSpotify, Error, TEXT("%s"), *Response->GetContentAsString());
354 | }
355 | }
356 |
357 | void USpotifyService::OnError(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful)
358 | {
359 |
360 | }
361 |
362 |
363 | void USpotifyService::Tick(float DeltaTime)
364 | {
365 | TCPListener();
366 | ConnectionListener();
367 | }
368 |
369 | bool USpotifyService::ShouldCreateSubsystem(UObject* Outer) const
370 | {
371 | return Super::ShouldCreateSubsystem(Outer);
372 | }
373 |
374 | void USpotifyService::Initialize(FSubsystemCollectionBase& Collection)
375 | {
376 | Super::Initialize(Collection);
377 | Http = &FModuleManager::LoadModuleChecked("Http").Get();
378 |
379 | const auto Settings = GetDefault();
380 | ClientKey = Settings->ClientId;
381 | RedirectURL = Settings->Callback;
382 | SaveSlotName = Settings->SaveSlotName;
383 |
384 | if(LoadCredentials())
385 | {
386 | RefreshAccessKey();
387 | return;
388 | }
389 |
390 |
391 | BeginAuthorization();
392 | }
393 |
394 | void USpotifyService::Deinitialize()
395 | {
396 | if(!RefreshKey.IsEmpty() && !Verify.IsEmpty() && !Challenge.IsEmpty())
397 | {
398 | SaveToSlot();
399 | }
400 | if(ConnectionSocket)
401 | {
402 | ConnectionSocket->Close();
403 | ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->DestroySocket(ConnectionSocket);
404 | }
405 | if(ServerSocket)
406 | {
407 | ServerSocket->Close();
408 | ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->DestroySocket(ServerSocket);
409 | }
410 | Super::Deinitialize();
411 | }
412 |
--------------------------------------------------------------------------------
/Config/DefaultInput.ini:
--------------------------------------------------------------------------------
1 |
2 | [/Script/Engine.InputSettings]
3 | +AxisConfig=(AxisKeyName="Gamepad_LeftX",AxisProperties=(DeadZone=0.250000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
4 | +AxisConfig=(AxisKeyName="Gamepad_LeftY",AxisProperties=(DeadZone=0.250000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
5 | +AxisConfig=(AxisKeyName="Gamepad_RightX",AxisProperties=(DeadZone=0.250000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
6 | +AxisConfig=(AxisKeyName="Gamepad_RightY",AxisProperties=(DeadZone=0.250000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
7 | +AxisConfig=(AxisKeyName="MouseX",AxisProperties=(DeadZone=0.000000,Sensitivity=0.070000,Exponent=1.000000,bInvert=False))
8 | +AxisConfig=(AxisKeyName="MouseY",AxisProperties=(DeadZone=0.000000,Sensitivity=0.070000,Exponent=1.000000,bInvert=False))
9 | +AxisConfig=(AxisKeyName="MouseWheelAxis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
10 | +AxisConfig=(AxisKeyName="Gamepad_LeftTriggerAxis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
11 | +AxisConfig=(AxisKeyName="Gamepad_RightTriggerAxis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
12 | +AxisConfig=(AxisKeyName="MotionController_Left_Thumbstick_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
13 | +AxisConfig=(AxisKeyName="MotionController_Left_Thumbstick_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
14 | +AxisConfig=(AxisKeyName="MotionController_Left_TriggerAxis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
15 | +AxisConfig=(AxisKeyName="MotionController_Left_Grip1Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
16 | +AxisConfig=(AxisKeyName="MotionController_Left_Grip2Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
17 | +AxisConfig=(AxisKeyName="MotionController_Right_Thumbstick_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
18 | +AxisConfig=(AxisKeyName="MotionController_Right_Thumbstick_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
19 | +AxisConfig=(AxisKeyName="MotionController_Right_TriggerAxis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
20 | +AxisConfig=(AxisKeyName="MotionController_Right_Grip1Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
21 | +AxisConfig=(AxisKeyName="MotionController_Right_Grip2Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
22 | +AxisConfig=(AxisKeyName="Gamepad_Special_Left_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
23 | +AxisConfig=(AxisKeyName="Gamepad_Special_Left_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
24 | +AxisConfig=(AxisKeyName="MotionController_Left_Thumbstick_Z",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
25 | +AxisConfig=(AxisKeyName="MotionController_Right_Thumbstick_Z",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
26 | +AxisConfig=(AxisKeyName="OculusTouch_Left_Thumbstick",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
27 | +AxisConfig=(AxisKeyName="OculusTouch_Left_FaceButton1",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
28 | +AxisConfig=(AxisKeyName="OculusTouch_Left_Trigger",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
29 | +AxisConfig=(AxisKeyName="OculusTouch_Left_FaceButton2",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
30 | +AxisConfig=(AxisKeyName="OculusTouch_Left_IndexPointing",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
31 | +AxisConfig=(AxisKeyName="OculusTouch_Left_ThumbUp",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
32 | +AxisConfig=(AxisKeyName="OculusTouch_Right_Thumbstick",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
33 | +AxisConfig=(AxisKeyName="OculusTouch_Right_FaceButton1",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
34 | +AxisConfig=(AxisKeyName="OculusTouch_Right_Trigger",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
35 | +AxisConfig=(AxisKeyName="OculusTouch_Right_FaceButton2",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
36 | +AxisConfig=(AxisKeyName="OculusTouch_Right_IndexPointing",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
37 | +AxisConfig=(AxisKeyName="OculusTouch_Right_ThumbUp",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
38 | +AxisConfig=(AxisKeyName="OculusTouchpad_Touchpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
39 | +AxisConfig=(AxisKeyName="OculusTouchpad_Touchpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
40 | +AxisConfig=(AxisKeyName="SteamVR_Knuckles_Left_HandGrip",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
41 | +AxisConfig=(AxisKeyName="SteamVR_Knuckles_Left_IndexGrip",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
42 | +AxisConfig=(AxisKeyName="SteamVR_Knuckles_Left_MiddleGrip",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
43 | +AxisConfig=(AxisKeyName="SteamVR_Knuckles_Left_RingGrip",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
44 | +AxisConfig=(AxisKeyName="SteamVR_Knuckles_Left_PinkyGrip",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
45 | +AxisConfig=(AxisKeyName="SteamVR_Knuckles_Right_HandGrip",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
46 | +AxisConfig=(AxisKeyName="SteamVR_Knuckles_Right_IndexGrip",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
47 | +AxisConfig=(AxisKeyName="SteamVR_Knuckles_Right_MiddleGrip",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
48 | +AxisConfig=(AxisKeyName="SteamVR_Knuckles_Right_RingGrip",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
49 | +AxisConfig=(AxisKeyName="SteamVR_Knuckles_Right_PinkyGrip",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
50 | +AxisConfig=(AxisKeyName="Daydream_Left_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
51 | +AxisConfig=(AxisKeyName="Daydream_Left_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
52 | +AxisConfig=(AxisKeyName="Daydream_Right_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
53 | +AxisConfig=(AxisKeyName="Daydream_Right_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
54 | +AxisConfig=(AxisKeyName="Vive_Left_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
55 | +AxisConfig=(AxisKeyName="Vive_Left_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
56 | +AxisConfig=(AxisKeyName="Vive_Left_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
57 | +AxisConfig=(AxisKeyName="Vive_Right_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
58 | +AxisConfig=(AxisKeyName="Vive_Right_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
59 | +AxisConfig=(AxisKeyName="Vive_Right_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
60 | +AxisConfig=(AxisKeyName="MixedReality_Left_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
61 | +AxisConfig=(AxisKeyName="MixedReality_Left_Thumbstick_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
62 | +AxisConfig=(AxisKeyName="MixedReality_Left_Thumbstick_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
63 | +AxisConfig=(AxisKeyName="MixedReality_Left_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
64 | +AxisConfig=(AxisKeyName="MixedReality_Left_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
65 | +AxisConfig=(AxisKeyName="MixedReality_Right_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
66 | +AxisConfig=(AxisKeyName="MixedReality_Right_Thumbstick_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
67 | +AxisConfig=(AxisKeyName="MixedReality_Right_Thumbstick_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
68 | +AxisConfig=(AxisKeyName="MixedReality_Right_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
69 | +AxisConfig=(AxisKeyName="MixedReality_Right_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
70 | +AxisConfig=(AxisKeyName="OculusGo_Left_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
71 | +AxisConfig=(AxisKeyName="OculusGo_Left_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
72 | +AxisConfig=(AxisKeyName="OculusGo_Right_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
73 | +AxisConfig=(AxisKeyName="OculusGo_Right_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
74 | +AxisConfig=(AxisKeyName="OculusTouch_Left_Grip_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
75 | +AxisConfig=(AxisKeyName="OculusTouch_Left_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
76 | +AxisConfig=(AxisKeyName="OculusTouch_Left_Thumbstick_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
77 | +AxisConfig=(AxisKeyName="OculusTouch_Left_Thumbstick_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
78 | +AxisConfig=(AxisKeyName="OculusTouch_Right_Grip_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
79 | +AxisConfig=(AxisKeyName="OculusTouch_Right_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
80 | +AxisConfig=(AxisKeyName="OculusTouch_Right_Thumbstick_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
81 | +AxisConfig=(AxisKeyName="OculusTouch_Right_Thumbstick_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
82 | +AxisConfig=(AxisKeyName="ValveIndex_Left_Grip_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
83 | +AxisConfig=(AxisKeyName="ValveIndex_Left_Grip_Force",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
84 | +AxisConfig=(AxisKeyName="ValveIndex_Left_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
85 | +AxisConfig=(AxisKeyName="ValveIndex_Left_Thumbstick_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
86 | +AxisConfig=(AxisKeyName="ValveIndex_Left_Thumbstick_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
87 | +AxisConfig=(AxisKeyName="ValveIndex_Left_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
88 | +AxisConfig=(AxisKeyName="ValveIndex_Left_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
89 | +AxisConfig=(AxisKeyName="ValveIndex_Left_Trackpad_Force",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
90 | +AxisConfig=(AxisKeyName="ValveIndex_Left_Trackpad_Touch",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
91 | +AxisConfig=(AxisKeyName="ValveIndex_Right_Grip_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
92 | +AxisConfig=(AxisKeyName="ValveIndex_Right_Grip_Force",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
93 | +AxisConfig=(AxisKeyName="ValveIndex_Right_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
94 | +AxisConfig=(AxisKeyName="ValveIndex_Right_Thumbstick_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
95 | +AxisConfig=(AxisKeyName="ValveIndex_Right_Thumbstick_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
96 | +AxisConfig=(AxisKeyName="ValveIndex_Right_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
97 | +AxisConfig=(AxisKeyName="ValveIndex_Right_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
98 | +AxisConfig=(AxisKeyName="ValveIndex_Right_Trackpad_Force",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
99 | bAltEnterTogglesFullscreen=True
100 | bF11TogglesFullscreen=True
101 | bUseMouseForTouch=False
102 | bEnableMouseSmoothing=True
103 | bEnableFOVScaling=True
104 | bCaptureMouseOnLaunch=True
105 | bAlwaysShowTouchInterface=False
106 | bShowConsoleOnFourFingerTap=True
107 | bEnableGestureRecognizer=False
108 | bUseAutocorrect=False
109 | DefaultViewportMouseCaptureMode=CapturePermanently_IncludingInitialMouseDown
110 | DefaultViewportMouseLockMode=LockOnCapture
111 | FOVScale=0.011110
112 | DoubleClickTime=0.200000
113 | +ActionMappings=(ActionName="Jump",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=SpaceBar)
114 | +ActionMappings=(ActionName="Jump",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=Gamepad_FaceButton_Bottom)
115 | +ActionMappings=(ActionName="Jump",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=Daydream_Left_Select_Click)
116 | +ActionMappings=(ActionName="ResetVR",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=R)
117 | +ActionMappings=(ActionName="ResetVR",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=Daydream_Left_Trackpad_Click)
118 | +ActionMappings=(ActionName="Jump",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=Vive_Left_Trigger_Click)
119 | +ActionMappings=(ActionName="Jump",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=Vive_Right_Trigger_Click)
120 | +ActionMappings=(ActionName="Jump",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=MixedReality_Left_Trigger_Click)
121 | +ActionMappings=(ActionName="Jump",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=MixedReality_Right_Trigger_Click)
122 | +ActionMappings=(ActionName="Jump",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=OculusGo_Left_Trigger_Click)
123 | +ActionMappings=(ActionName="Jump",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=OculusTouch_Left_Trigger_Click)
124 | +ActionMappings=(ActionName="Jump",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=OculusTouch_Right_Trigger_Click)
125 | +ActionMappings=(ActionName="Jump",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=ValveIndex_Left_Trigger_Click)
126 | +ActionMappings=(ActionName="Jump",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=ValveIndex_Right_Trigger_Click)
127 | +ActionMappings=(ActionName="Jump",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=MagicLeap_Left_Trigger)
128 | +ActionMappings=(ActionName="ResetVR",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=Vive_Left_Grip_Click)
129 | +ActionMappings=(ActionName="ResetVR",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=MixedReality_Left_Thumbstick_Click)
130 | +ActionMappings=(ActionName="ResetVR",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=OculusGo_Left_Trackpad_Click)
131 | +ActionMappings=(ActionName="ResetVR",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=OculusTouch_Left_Thumbstick_Click)
132 | +ActionMappings=(ActionName="ResetVR",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=ValveIndex_Left_Thumbstick_Click)
133 | +ActionMappings=(ActionName="ResetVR",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=MagicLeap_Left_Bumper)
134 | +AxisMappings=(AxisName="MoveForward",Scale=1.000000,Key=W)
135 | +AxisMappings=(AxisName="MoveForward",Scale=-1.000000,Key=S)
136 | +AxisMappings=(AxisName="MoveForward",Scale=1.000000,Key=Up)
137 | +AxisMappings=(AxisName="MoveForward",Scale=-1.000000,Key=Down)
138 | +AxisMappings=(AxisName="MoveForward",Scale=1.000000,Key=Gamepad_LeftY)
139 | +AxisMappings=(AxisName="MoveRight",Scale=-1.000000,Key=A)
140 | +AxisMappings=(AxisName="MoveRight",Scale=1.000000,Key=D)
141 | +AxisMappings=(AxisName="MoveRight",Scale=1.000000,Key=Gamepad_LeftX)
142 | +AxisMappings=(AxisName="TurnRate",Scale=1.000000,Key=Gamepad_RightX)
143 | +AxisMappings=(AxisName="TurnRate",Scale=-1.000000,Key=Left)
144 | +AxisMappings=(AxisName="TurnRate",Scale=1.000000,Key=Right)
145 | +AxisMappings=(AxisName="Turn",Scale=1.000000,Key=MouseX)
146 | +AxisMappings=(AxisName="LookUpRate",Scale=1.000000,Key=Gamepad_RightY)
147 | +AxisMappings=(AxisName="LookUp",Scale=-1.000000,Key=MouseY)
148 | +AxisMappings=(AxisName="TurnRate",Scale=-1.000000,Key=Vive_Right_Trackpad_X)
149 | +AxisMappings=(AxisName="MoveForward",Scale=1.000000,Key=Daydream_Left_Trackpad_Y)
150 | +AxisMappings=(AxisName="MoveForward",Scale=1.000000,Key=Vive_Left_Trackpad_Y)
151 | +AxisMappings=(AxisName="MoveRight",Scale=1.000000,Key=Daydream_Left_Trackpad_X)
152 | +AxisMappings=(AxisName="MoveRight",Scale=1.000000,Key=Vive_Left_Trackpad_X)
153 | +AxisMappings=(AxisName="MoveRight",Scale=1.000000,Key=MixedReality_Left_Thumbstick_X)
154 | +AxisMappings=(AxisName="MoveRight",Scale=1.000000,Key=OculusGo_Left_Trackpad_X)
155 | +AxisMappings=(AxisName="MoveForward",Scale=1.000000,Key=MixedReality_Left_Thumbstick_Y)
156 | +AxisMappings=(AxisName="MoveForward",Scale=1.000000,Key=OculusGo_Left_Trackpad_Y)
157 | +AxisMappings=(AxisName="TurnRate",Scale=-1.000000,Key=MixedReality_Right_Thumbstick_X)
158 | +AxisMappings=(AxisName="TurnRate",Scale=-1.000000,Key=OculusTouch_Right_Thumbstick_X)
159 | +AxisMappings=(AxisName="TurnRate",Scale=-1.000000,Key=ValveIndex_Right_Thumbstick_X)
160 | +AxisMappings=(AxisName="MoveForward",Scale=1.000000,Key=OculusTouch_Left_Thumbstick_Y)
161 | +AxisMappings=(AxisName="MoveForward",Scale=1.000000,Key=ValveIndex_Left_Thumbstick_Y)
162 | +AxisMappings=(AxisName="MoveForward",Scale=1.000000,Key=MagicLeap_Left_Trackpad_Y)
163 | +AxisMappings=(AxisName="MoveRight",Scale=1.000000,Key=OculusTouch_Left_Thumbstick_X)
164 | +AxisMappings=(AxisName="MoveRight",Scale=1.000000,Key=ValveIndex_Left_Thumbstick_X)
165 | +AxisMappings=(AxisName="MoveRight",Scale=1.000000,Key=MagicLeap_Left_Trackpad_X)
166 | DefaultTouchInterface=/Engine/MobileResources/HUD/DefaultVirtualJoysticks.DefaultVirtualJoysticks
167 | +ConsoleKeys=Tilde
168 |
169 |
170 |
--------------------------------------------------------------------------------