Merge branch 'LBPUnion:main' into main

This commit is contained in:
LumaLivy 2021-11-13 14:00:09 -05:00 committed by GitHub
commit 13f20b2959
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
25 changed files with 884 additions and 41 deletions

View file

@ -36,17 +36,10 @@ jobs:
if: ${{ matrix.os.database }} if: ${{ matrix.os.database }}
run: mysql -u${{ env.DB_USER }} -p${{ env.DB_PASSWORD }} -h 127.0.0.1 -e "CREATE DATABASE ${{ env.DB_DATABASE }};"; run: mysql -u${{ env.DB_USER }} -p${{ env.DB_PASSWORD }} -h 127.0.0.1 -e "CREATE DATABASE ${{ env.DB_DATABASE }};";
- name: Install .NET 5.0 - name: Install .NET 6.0
uses: actions/setup-dotnet@v1
with:
dotnet-version: "5.0.x"
include-prerelease: true
- name: Install .NET 6.0 Preview
uses: actions/setup-dotnet@v1 uses: actions/setup-dotnet@v1
with: with:
dotnet-version: "6.0.x" dotnet-version: "6.0.x"
include-prerelease: true
- name: Compile - name: Compile
run: dotnet build -c Debug run: dotnet build -c Debug

View file

@ -5,7 +5,7 @@
<IsPackable>false</IsPackable> <IsPackable>false</IsPackable>
<TargetFrameworks>net5.0;net6.0</TargetFrameworks> <TargetFramework>net6.0</TargetFramework>
<AssemblyName>LBPUnion.ProjectLighthouse.Tests</AssemblyName> <AssemblyName>LBPUnion.ProjectLighthouse.Tests</AssemblyName>

View file

@ -73,6 +73,7 @@
<s:String x:Key="/Default/CodeStyle/CSharpVarKeywordUsage/ForSimpleTypes/@EntryValue">UseExplicitType</s:String> <s:String x:Key="/Default/CodeStyle/CSharpVarKeywordUsage/ForSimpleTypes/@EntryValue">UseExplicitType</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=LBP/@EntryIndexedValue">LBP</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=LBP/@EntryIndexedValue">LBP</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=MM/@EntryIndexedValue">MM</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=MM/@EntryIndexedValue">MM</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=NAT/@EntryIndexedValue">NAT</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=NP/@EntryIndexedValue">NP</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=NP/@EntryIndexedValue">NP</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=Method/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb"&gt;&lt;ExtraRule Prefix="" Suffix="" Style="aaBb" /&gt;&lt;/Policy&gt;</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=Method/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb"&gt;&lt;ExtraRule Prefix="" Suffix="" Style="aaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateConstants/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateConstants/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>

View file

@ -17,7 +17,7 @@ namespace LBPUnion.ProjectLighthouse.Controllers
HostString hostname = this.Request.Host; HostString hostname = this.Request.Host;
return this.Ok return this.Ok
( (
"ProbabilityOfPacketDelay 0.0\nMinPacketDelayFrames 0\nMaxPacketDelayFrames 3\nProbabilityOfPacketDrop 0.0\nEnableFakeConditionsForLoopback true\nNumberOfFramesPredictionAllowedForNonLocalPlayer 1000\nEnablePrediction true\nMinPredictedFrames 0\nMaxPredictedFrames 10\nAllowGameRendCameraSplit true\nFramesBeforeAgressiveCatchup 30\nPredictionPadSides 200\nPredictionPadTop 200\nPredictionPadBottom 200\nShowErrorNumbers true\nAllowModeratedLevels true\nAllowModeratedPoppetItems true\nShowLevelBoos true\nTIMEOUT_WAIT_FOR_JOIN_RESPONSE_FROM_PREV_PARTY_HOST 50.0\nTIMEOUT_WAIT_FOR_CHANGE_LEVEL_PARTY_HOST 30.0\nTIMEOUT_WAIT_FOR_CHANGE_LEVEL_PARTY_MEMBER 45.0\nTIMEOUT_WAIT_FOR_REQUEST_JOIN_FRIEND 15.0\nTIMEOUT_WAIT_FOR_CONNECTION_FROM_HOST 30.0\nTIMEOUT_WAIT_FOR_ROOM_ID_TO_JOIN 60.0\nTIMEOUT_WAIT_FOR_GET_NUM_PLAYERS_ONLINE 60.0\nTIMEOUT_WAIT_FOR_SIGNALLING_CONNECTIONS 120.0\nTIMEOUT_WAIT_FOR_PARTY_DATA 60.0\nTIME_TO_WAIT_FOR_LEAVE_MESSAGE_TO_COME_BACK 20.0\nTIME_TO_WAIT_FOR_FOLLOWING_REQUESTS_TO_ARRIVE 30.0\nTIMEOUT_WAIT_FOR_FINISHED_MIGRATING_HOST 30.0\nTIMEOUT_WAIT_FOR_PARTY_LEADER_FINISH_JOINING 45.0\nTIMEOUT_WAIT_FOR_QUICKPLAY_LEVEL 60.0\nTIMEOUT_WAIT_FOR_PLAYERS_TO_JOIN 30.0\nTIMEOUT_WAIT_FOR_DIVE_IN_PLAYERS 120.0\nTIMEOUT_WAIT_FOR_FIND_BEST_ROOM 30.0\nTIMEOUT_DIVE_IN_TOTAL 1000000.0\nTIMEOUT_WAIT_FOR_SOCKET_CONNECTION 120.0\nTIMEOUT_WAIT_FOR_REQUEST_RESOURCE_MESSAGE 120.0\nTIMEOUT_WAIT_FOR_LOCAL_CLIENT_TO_GET_RESOURCE_LIST 120.0\nTIMEOUT_WAIT_FOR_CLIENT_TO_LOAD_RESOURCES 120.0\nTIMEOUT_WAIT_FOR_LOCAL_CLIENT_TO_SAVE_GAME_STATE 30.0\nTIMEOUT_WAIT_FOR_ADD_PLAYERS_TO_TAKE 30.0\nTIMEOUT_WAIT_FOR_UPDATE_FROM_CLIENT 90.0\nTIMEOUT_WAIT_FOR_HOST_TO_GET_RESOURCE_LIST 60.0\nTIMEOUT_WAIT_FOR_HOST_TO_SAVE_GAME_STATE 60.0\nTIMEOUT_WAIT_FOR_HOST_TO_ADD_US 30.0\nTIMEOUT_WAIT_FOR_UPDATE 60.0\nTIMEOUT_WAIT_FOR_REQUEST_JOIN 50.0\nTIMEOUT_WAIT_FOR_AUTOJOIN_PRESENCE 60.0\nTIMEOUT_WAIT_FOR_AUTOJOIN_CONNECTION 120.0\nSECONDS_BETWEEN_PINS_AWARDED_UPLOADS 300.0\nEnableKeepAlive true\nAllowVoIPRecordingPlayback true\nCDNHostName localhost\nTelemetryServer localhost\nOverheatingThresholdDisallowMidgameJoin 0.95\nMaxCatchupFrames 3\nMaxLagBeforeShowLoading 23\nMinLagBeforeHideLoading 30\nLagImprovementInflectionPoint -1.0\nFlickerThreshold 2.0\nClosedDemo2014Version 1\nClosedDemo2014Expired false\nEnablePlayedFilter true\nEnableCommunityDecorations true\nGameStateUpdateRate 10.0\nGameStateUpdateRateWithConsumers 1.0\nDisableDLCPublishCheck false\nEnableDiveIn true\nEnableHackChecks false\n" + "ProbabilityOfPacketDelay 0.0\nMinPacketDelayFrames 0\nMaxPacketDelayFrames 3\nProbabilityOfPacketDrop 0.0\nEnableFakeConditionsForLoopback true\nNumberOfFramesPredictionAllowedForNonLocalPlayer 1000\nEnablePrediction true\nMinPredictedFrames 0\nMaxPredictedFrames 10\nAllowGameRendCameraSplit true\nFramesBeforeAgressiveCatchup 30\nPredictionPadSides 200\nPredictionPadTop 200\nPredictionPadBottom 200\nShowErrorNumbers true\nAllowModeratedLevels true\nAllowModeratedPoppetItems true\nShowLevelBoos true\nTIMEOUT_WAIT_FOR_JOIN_RESPONSE_FROM_PREV_PARTY_HOST 50.0\nTIMEOUT_WAIT_FOR_CHANGE_LEVEL_PARTY_HOST 30.0\nTIMEOUT_WAIT_FOR_CHANGE_LEVEL_PARTY_MEMBER 45.0\nTIMEOUT_WAIT_FOR_REQUEST_JOIN_FRIEND 15.0\nTIMEOUT_WAIT_FOR_CONNECTION_FROM_HOST 30.0\nTIMEOUT_WAIT_FOR_ROOM_ID_TO_JOIN 60.0\nTIMEOUT_WAIT_FOR_GET_NUM_PLAYERS_ONLINE 60.0\nTIMEOUT_WAIT_FOR_SIGNALLING_CONNECTIONS 120.0\nTIMEOUT_WAIT_FOR_PARTY_DATA 60.0\nTIME_TO_WAIT_FOR_LEAVE_MESSAGE_TO_COME_BACK 20.0\nTIME_TO_WAIT_FOR_FOLLOWING_REQUESTS_TO_ARRIVE 30.0\nTIMEOUT_WAIT_FOR_FINISHED_MIGRATING_HOST 30.0\nTIMEOUT_WAIT_FOR_PARTY_LEADER_FINISH_JOINING 45.0\nTIMEOUT_WAIT_FOR_QUICKPLAY_LEVEL 60.0\nTIMEOUT_WAIT_FOR_PLAYERS_TO_JOIN 30.0\nTIMEOUT_WAIT_FOR_DIVE_IN_PLAYERS 240.0\nTIMEOUT_WAIT_FOR_FIND_BEST_ROOM 60.0\nTIMEOUT_DIVE_IN_TOTAL 300.0\nTIMEOUT_WAIT_FOR_SOCKET_CONNECTION 120.0\nTIMEOUT_WAIT_FOR_REQUEST_RESOURCE_MESSAGE 120.0\nTIMEOUT_WAIT_FOR_LOCAL_CLIENT_TO_GET_RESOURCE_LIST 120.0\nTIMEOUT_WAIT_FOR_CLIENT_TO_LOAD_RESOURCES 120.0\nTIMEOUT_WAIT_FOR_LOCAL_CLIENT_TO_SAVE_GAME_STATE 30.0\nTIMEOUT_WAIT_FOR_ADD_PLAYERS_TO_TAKE 30.0\nTIMEOUT_WAIT_FOR_UPDATE_FROM_CLIENT 90.0\nTIMEOUT_WAIT_FOR_HOST_TO_GET_RESOURCE_LIST 60.0\nTIMEOUT_WAIT_FOR_HOST_TO_SAVE_GAME_STATE 60.0\nTIMEOUT_WAIT_FOR_HOST_TO_ADD_US 30.0\nTIMEOUT_WAIT_FOR_UPDATE 60.0\nTIMEOUT_WAIT_FOR_REQUEST_JOIN 50.0\nTIMEOUT_WAIT_FOR_AUTOJOIN_PRESENCE 60.0\nTIMEOUT_WAIT_FOR_AUTOJOIN_CONNECTION 120.0\nSECONDS_BETWEEN_PINS_AWARDED_UPLOADS 300.0\nEnableKeepAlive true\nAllowVoIPRecordingPlayback true\nCDNHostName localhost\nTelemetryServer localhost\nOverheatingThresholdDisallowMidgameJoin 0.95\nMaxCatchupFrames 3\nMaxLagBeforeShowLoading 23\nMinLagBeforeHideLoading 30\nLagImprovementInflectionPoint -1.0\nFlickerThreshold 2.0\nClosedDemo2014Version 1\nClosedDemo2014Expired false\nEnablePlayedFilter true\nEnableCommunityDecorations true\nGameStateUpdateRate 10.0\nGameStateUpdateRateWithConsumers 1.0\nDisableDLCPublishCheck false\nEnableDiveIn true\nEnableHackChecks false\n" +
$"TelemetryServer {hostname}\nCDNHostName {hostname}" $"TelemetryServer {hostname}\nCDNHostName {hostname}"
); );
} }

View file

@ -74,7 +74,7 @@ namespace LBPUnion.ProjectLighthouse.Controllers
if (!FriendHelper.FriendIdsByUserId.TryGetValue(user.UserId, out int[]? friendIds) || friendIds == null) if (!FriendHelper.FriendIdsByUserId.TryGetValue(user.UserId, out int[]? friendIds) || friendIds == null)
{ {
return this.NotFound(); return this.Ok(LbpSerializer.BlankElement("myFriends"));
} }
string friends = ""; string friends = "";

View file

@ -1,5 +1,6 @@
#nullable enable #nullable enable
using System.IO; using System.IO;
using System.Net;
using System.Threading.Tasks; using System.Threading.Tasks;
using Kettu; using Kettu;
using LBPUnion.ProjectLighthouse.Logging; using LBPUnion.ProjectLighthouse.Logging;
@ -39,7 +40,12 @@ namespace LBPUnion.ProjectLighthouse.Controllers
} }
if (loginData == null) return this.BadRequest(); if (loginData == null) return this.BadRequest();
Token? token = await this.database.AuthenticateUser(loginData, titleId); IPAddress? ipAddress = this.HttpContext.Connection.RemoteIpAddress;
if (ipAddress == null) return this.StatusCode(403, ""); // 403 probably isnt the best status code for this, but whatever
string userLocation = ipAddress.ToString();
Token? token = await this.database.AuthenticateUser(loginData, userLocation, titleId);
if (token == null) return this.StatusCode(403, ""); if (token == null) return this.StatusCode(403, "");
Logger.Log Logger.Log

View file

@ -2,11 +2,11 @@
using System; using System;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text.Json;
using System.Threading.Tasks; using System.Threading.Tasks;
using Kettu; using Kettu;
using LBPUnion.ProjectLighthouse.Helpers; using LBPUnion.ProjectLighthouse.Helpers;
using LBPUnion.ProjectLighthouse.Types; using LBPUnion.ProjectLighthouse.Types;
using LBPUnion.ProjectLighthouse.Types.Levels;
using LBPUnion.ProjectLighthouse.Types.Match; using LBPUnion.ProjectLighthouse.Types.Match;
using LBPUnion.ProjectLighthouse.Types.Profiles; using LBPUnion.ProjectLighthouse.Types.Profiles;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
@ -27,13 +27,16 @@ namespace LBPUnion.ProjectLighthouse.Controllers
} }
[HttpPost("match")] [HttpPost("match")]
[Produces("text/json")] [Produces("text/plain")]
public async Task<IActionResult> Match() public async Task<IActionResult> Match()
{ {
(User, Token)? userAndToken = await this.database.UserAndTokenFromRequest(this.Request);
User? user = await this.database.UserFromRequest(this.Request); if (userAndToken == null) return this.StatusCode(403, "");
if (user == null) return this.StatusCode(403, ""); // ReSharper disable once PossibleInvalidOperationException
User user = userAndToken.Value.Item1;
Token token = userAndToken.Value.Item2;
#region Parse match data #region Parse match data
@ -61,25 +64,30 @@ namespace LBPUnion.ProjectLighthouse.Controllers
#endregion #endregion
#region Process match data #region Process match data
/*
if (matchData is CreateRoom createRoom) if (matchData is UpdateMyPlayerData) MatchHelper.SetUserLocation(user.UserId, token.UserLocation);
if (matchData is FindBestRoom && MatchHelper.UserLocations.Count > 1)
{ {
if (createRoom.Slots.Count == 0) return this.BadRequest(); foreach ((int id, string? location) in MatchHelper.UserLocations)
if (createRoom.FirstSlot.Count != 2) return this.BadRequest();
int slotType = createRoom.FirstSlot[0];
int slotId = createRoom.FirstSlot[1];
if (slotType == 1)
{ {
Slot? slot = await this.database.Slots.FirstOrDefaultAsync(s => s.SlotId == slotId); if (id == user.UserId) continue;
if (slot == null) return this.BadRequest(); if (location == null) continue;
if (MatchHelper.DidUserRecentlyDiveInWith(user.UserId, id)) continue;
slot.Plays++; User? otherUser = await this.database.Users.FirstOrDefaultAsync(u => u.UserId == id);
await this.database.SaveChangesAsync(); if (otherUser == null) continue;
FindBestRoomResponse response = MatchHelper.FindBestRoomResponse(user.Username, otherUser.Username, token.UserLocation, location);
string serialized = JsonSerializer.Serialize(response, typeof(FindBestRoomResponse));
MatchHelper.AddUserRecentlyDivedIn(user.UserId, id);
return new ObjectResult($"[{{\"StatusCode\":200}},{serialized}]");
} }
} }
*/
#endregion #endregion
#region Update LastMatch #region Update LastMatch

View file

@ -71,7 +71,7 @@ namespace LBPUnion.ProjectLighthouse.Controllers
[HttpGet("photos/user/{id:int}")] [HttpGet("photos/user/{id:int}")]
public async Task<IActionResult> SlotPhotos(int id) public async Task<IActionResult> SlotPhotos(int id)
{ {
List<Photo> photos = await this.database.Photos.Take(10).ToListAsync(); List<Photo> photos = await this.database.Photos.Include(p => p.Creator).Take(10).ToListAsync();
string response = photos.Aggregate(string.Empty, (s, photo) => s + photo.Serialize(id)); string response = photos.Aggregate(string.Empty, (s, photo) => s + photo.Serialize(id));
return this.Ok(LbpSerializer.StringElement("photos", response)); return this.Ok(LbpSerializer.StringElement("photos", response));
} }
@ -83,7 +83,9 @@ namespace LBPUnion.ProjectLighthouse.Controllers
// ReSharper disable once ConditionIsAlwaysTrueOrFalse // ReSharper disable once ConditionIsAlwaysTrueOrFalse
if (user == null) return this.NotFound(); if (user == null) return this.NotFound();
List<Photo> photos = await this.database.Photos.Where(p => p.CreatorId == userFromQuery.UserId) List<Photo> photos = await this.database.Photos.Include
(p => p.Creator)
.Where(p => p.CreatorId == userFromQuery.UserId)
.OrderByDescending(s => s.Timestamp) .OrderByDescending(s => s.Timestamp)
.Skip(pageStart - 1) .Skip(pageStart - 1)
.Take(Math.Min(pageSize, 30)) .Take(Math.Min(pageSize, 30))
@ -100,7 +102,7 @@ namespace LBPUnion.ProjectLighthouse.Controllers
if (user == null) return this.NotFound(); if (user == null) return this.NotFound();
List<Photo> photos = new(); List<Photo> photos = new();
foreach (Photo photo in this.database.Photos) foreach (Photo photo in this.database.Photos.Include(p => p.Creator))
{ {
photos.AddRange(photo.Subjects.Where(subject => subject.User.UserId == userFromQuery.UserId).Select(_ => photo)); photos.AddRange(photo.Subjects.Where(subject => subject.User.UserId == userFromQuery.UserId).Select(_ => photo));
} }
@ -113,5 +115,20 @@ namespace LBPUnion.ProjectLighthouse.Controllers
return this.Ok(LbpSerializer.StringElement("photos", response)); return this.Ok(LbpSerializer.StringElement("photos", response));
} }
[HttpPost("deletePhoto/{id:int}")]
public async Task<IActionResult> DeletePhoto(int id)
{
User? user = await this.database.UserFromRequest(this.Request);
if (user == null) return this.StatusCode(403, "");
Photo? photo = await this.database.Photos.FirstOrDefaultAsync(p => p.PhotoId == id);
if (photo == null) return this.NotFound();
if (photo.CreatorId != user.UserId) return this.StatusCode(401, "");
this.database.Photos.Remove(photo);
await this.database.SaveChangesAsync();
return this.Ok();
}
} }
} }

View file

@ -55,7 +55,7 @@ namespace LBPUnion.ProjectLighthouse
} }
#nullable enable #nullable enable
public async Task<Token?> AuthenticateUser(LoginData loginData, string titleId = "") public async Task<Token?> AuthenticateUser(LoginData loginData, string userLocation, string titleId = "")
{ {
// TODO: don't use psn name to authenticate // TODO: don't use psn name to authenticate
User user = await this.Users.FirstOrDefaultAsync(u => u.Username == loginData.Username) ?? await this.CreateUser(loginData.Username); User user = await this.Users.FirstOrDefaultAsync(u => u.Username == loginData.Username) ?? await this.CreateUser(loginData.Username);
@ -64,6 +64,7 @@ namespace LBPUnion.ProjectLighthouse
{ {
UserToken = HashHelper.GenerateAuthToken(), UserToken = HashHelper.GenerateAuthToken(),
UserId = user.UserId, UserId = user.UserId,
UserLocation = userLocation,
GameVersion = GameVersionHelper.FromTitleId(titleId), GameVersion = GameVersionHelper.FromTitleId(titleId),
}; };

View file

@ -27,6 +27,7 @@ namespace LBPUnion.ProjectLighthouse.Helpers
LbpFileType.Voice => true, LbpFileType.Voice => true,
LbpFileType.Plan => true, LbpFileType.Plan => true,
LbpFileType.Jpeg => true, LbpFileType.Jpeg => true,
LbpFileType.Png => true,
#if DEBUG #if DEBUG
_ => throw new ArgumentOutOfRangeException(nameof(file), $"Unhandled file type ({file.FileType}) in FileHelper.IsFileSafe()"), _ => throw new ArgumentOutOfRangeException(nameof(file), $"Unhandled file type ({file.FileType}) in FileHelper.IsFileSafe()"),
#else #else
@ -66,10 +67,11 @@ namespace LBPUnion.ProjectLighthouse.Helpers
{ {
reader.BaseStream.Position = 0; reader.BaseStream.Position = 0;
// Determine if file is JPEG // Determine if file is JPEG/PNG
byte[] header = reader.ReadBytes(9); byte[] header = reader.ReadBytes(9);
if (header[0] == 0xFF && header[1] == 0xD8 && header[2] == 0xFF && header[3] == 0xE0) return LbpFileType.Jpeg; if (header[0] == 0xFF && header[1] == 0xD8 && header[2] == 0xFF && header[3] == 0xE0) return LbpFileType.Jpeg;
if (header[0] == 0x89 && header[1] == 0x50 && header[2] == 0x4E && header[3] == 0x47) return LbpFileType.Png;
return LbpFileType.Unknown; // Still unknown. return LbpFileType.Unknown; // Still unknown.
} }

View file

@ -1,5 +1,7 @@
#nullable enable #nullable enable
using System; using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Text.Json; using System.Text.Json;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
@ -9,6 +11,65 @@ namespace LBPUnion.ProjectLighthouse.Helpers
{ {
public static class MatchHelper public static class MatchHelper
{ {
public static readonly Dictionary<int, string?> UserLocations = new();
public static readonly Dictionary<int, List<int>?> UserRecentlyDivedIn = new();
public static void SetUserLocation(int userId, string location)
{
if (UserLocations.TryGetValue(userId, out string? _)) UserLocations.Remove(userId);
UserLocations.Add(userId, location);
}
public static void AddUserRecentlyDivedIn(int userId, int otherUserId)
{
if (!UserRecentlyDivedIn.TryGetValue(userId, out List<int>? recentlyDivedIn))
{
UserRecentlyDivedIn.Add(userId, recentlyDivedIn = new List<int>());
}
Debug.Assert(recentlyDivedIn != null, nameof(recentlyDivedIn) + " is null, somehow.");
recentlyDivedIn.Add(otherUserId);
}
public static bool DidUserRecentlyDiveInWith(int userId, int otherUserId)
{
if (!UserRecentlyDivedIn.TryGetValue(userId, out List<int>? recentlyDivedIn) || recentlyDivedIn == null) return false;
return recentlyDivedIn.Contains(otherUserId);
}
public static FindBestRoomResponse FindBestRoomResponse(string username, string otherUsername, string location, string otherLocation)
=> new()
{
Players = new List<Player>
{
new()
{
MatchingRes = 0,
PlayerId = otherUsername,
},
new()
{
MatchingRes = 1,
PlayerId = username,
},
},
Locations = new List<string>
{
location,
otherLocation,
},
Slots = new List<List<int>>
{
new()
{
5,
0,
},
},
};
public static IMatchData? Deserialize(string data) public static IMatchData? Deserialize(string data)
{ {
string matchType = ""; string matchType = "";
@ -37,6 +98,7 @@ namespace LBPUnion.ProjectLighthouse.Helpers
"UpdateMyPlayerData" => JsonSerializer.Deserialize<UpdateMyPlayerData>(matchData), "UpdateMyPlayerData" => JsonSerializer.Deserialize<UpdateMyPlayerData>(matchData),
"UpdatePlayersInRoom" => JsonSerializer.Deserialize<UpdatePlayersInRoom>(matchData), "UpdatePlayersInRoom" => JsonSerializer.Deserialize<UpdatePlayersInRoom>(matchData),
"CreateRoom" => JsonSerializer.Deserialize<CreateRoom>(matchData), "CreateRoom" => JsonSerializer.Deserialize<CreateRoom>(matchData),
"FindBestRoom" => JsonSerializer.Deserialize<FindBestRoom>(matchData),
_ => null, _ => null,
}; };
} }

View file

@ -0,0 +1,638 @@
// <auto-generated />
using LBPUnion.ProjectLighthouse;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace ProjectLighthouse.Migrations
{
[DbContext(typeof(Database))]
[Migration("20211113091631_AddUserLocationToToken")]
partial class AddUserLocationToToken
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("Relational:MaxIdentifierLength", 64)
.HasAnnotation("ProductVersion", "5.0.12");
modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.HeartedProfile", b =>
{
b.Property<int>("HeartedProfileId")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<int>("HeartedUserId")
.HasColumnType("int");
b.Property<int>("UserId")
.HasColumnType("int");
b.HasKey("HeartedProfileId");
b.HasIndex("HeartedUserId");
b.HasIndex("UserId");
b.ToTable("HeartedProfiles");
});
modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Levels.HeartedLevel", b =>
{
b.Property<int>("HeartedLevelId")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<int>("SlotId")
.HasColumnType("int");
b.Property<int>("UserId")
.HasColumnType("int");
b.HasKey("HeartedLevelId");
b.HasIndex("SlotId");
b.HasIndex("UserId");
b.ToTable("HeartedLevels");
});
modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Levels.QueuedLevel", b =>
{
b.Property<int>("QueuedLevelId")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<int>("SlotId")
.HasColumnType("int");
b.Property<int>("UserId")
.HasColumnType("int");
b.HasKey("QueuedLevelId");
b.HasIndex("SlotId");
b.HasIndex("UserId");
b.ToTable("QueuedLevels");
});
modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Levels.RatedLevel", b =>
{
b.Property<int>("RatedLevelId")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<int>("Rating")
.HasColumnType("int");
b.Property<double>("RatingLBP1")
.HasColumnType("double");
b.Property<int>("SlotId")
.HasColumnType("int");
b.Property<int>("UserId")
.HasColumnType("int");
b.HasKey("RatedLevelId");
b.HasIndex("SlotId");
b.HasIndex("UserId");
b.ToTable("RatedLevels");
});
modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Levels.Slot", b =>
{
b.Property<int>("SlotId")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<string>("AuthorLabels")
.HasColumnType("longtext");
b.Property<string>("BackgroundHash")
.HasColumnType("longtext");
b.Property<int>("CreatorId")
.HasColumnType("int");
b.Property<string>("Description")
.HasColumnType("longtext");
b.Property<long>("FirstUploaded")
.HasColumnType("bigint");
b.Property<int>("GameVersion")
.HasColumnType("int");
b.Property<string>("IconHash")
.HasColumnType("longtext");
b.Property<bool>("InitiallyLocked")
.HasColumnType("tinyint(1)");
b.Property<long>("LastUpdated")
.HasColumnType("bigint");
b.Property<bool>("Lbp1Only")
.HasColumnType("tinyint(1)");
b.Property<string>("LevelType")
.HasColumnType("longtext");
b.Property<int>("LocationId")
.HasColumnType("int");
b.Property<int>("MaximumPlayers")
.HasColumnType("int");
b.Property<int>("MinimumPlayers")
.HasColumnType("int");
b.Property<bool>("MoveRequired")
.HasColumnType("tinyint(1)");
b.Property<string>("Name")
.HasColumnType("longtext");
b.Property<int>("PlaysLBP1")
.HasColumnType("int");
b.Property<int>("PlaysLBP1Complete")
.HasColumnType("int");
b.Property<int>("PlaysLBP1Unique")
.HasColumnType("int");
b.Property<int>("PlaysLBP2")
.HasColumnType("int");
b.Property<int>("PlaysLBP2Complete")
.HasColumnType("int");
b.Property<int>("PlaysLBP2Unique")
.HasColumnType("int");
b.Property<int>("PlaysLBP3")
.HasColumnType("int");
b.Property<int>("PlaysLBP3Complete")
.HasColumnType("int");
b.Property<int>("PlaysLBP3Unique")
.HasColumnType("int");
b.Property<string>("ResourceCollection")
.HasColumnType("longtext");
b.Property<string>("RootLevel")
.HasColumnType("longtext");
b.Property<int>("Shareable")
.HasColumnType("int");
b.Property<bool>("SubLevel")
.HasColumnType("tinyint(1)");
b.Property<bool>("TeamPick")
.HasColumnType("tinyint(1)");
b.HasKey("SlotId");
b.HasIndex("CreatorId");
b.HasIndex("LocationId");
b.ToTable("Slots");
});
modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Levels.VisitedLevel", b =>
{
b.Property<int>("VisitedLevelId")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<int>("GameVersion")
.HasColumnType("int");
b.Property<int>("SlotId")
.HasColumnType("int");
b.Property<int>("UserId")
.HasColumnType("int");
b.HasKey("VisitedLevelId");
b.HasIndex("SlotId");
b.HasIndex("UserId");
b.ToTable("VisitedLevels");
});
modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Photo", b =>
{
b.Property<int>("PhotoId")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<int>("CreatorId")
.HasColumnType("int");
b.Property<string>("LargeHash")
.IsRequired()
.HasColumnType("longtext");
b.Property<string>("MediumHash")
.IsRequired()
.HasColumnType("longtext");
b.Property<string>("PhotoSubjectCollection")
.IsRequired()
.HasColumnType("longtext");
b.Property<string>("PlanHash")
.IsRequired()
.HasColumnType("longtext");
b.Property<string>("SmallHash")
.IsRequired()
.HasColumnType("longtext");
b.Property<long>("Timestamp")
.HasColumnType("bigint");
b.HasKey("PhotoId");
b.HasIndex("CreatorId");
b.ToTable("Photos");
});
modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.PhotoSubject", b =>
{
b.Property<int>("PhotoSubjectId")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<string>("Bounds")
.HasColumnType("longtext");
b.Property<int>("UserId")
.HasColumnType("int");
b.HasKey("PhotoSubjectId");
b.HasIndex("UserId");
b.ToTable("PhotoSubjects");
});
modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Profiles.Comment", b =>
{
b.Property<int>("CommentId")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<string>("Message")
.HasColumnType("longtext");
b.Property<int>("PosterUserId")
.HasColumnType("int");
b.Property<int>("TargetUserId")
.HasColumnType("int");
b.Property<int>("ThumbsDown")
.HasColumnType("int");
b.Property<int>("ThumbsUp")
.HasColumnType("int");
b.Property<long>("Timestamp")
.HasColumnType("bigint");
b.HasKey("CommentId");
b.HasIndex("PosterUserId");
b.HasIndex("TargetUserId");
b.ToTable("Comments");
});
modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Profiles.LastMatch", b =>
{
b.Property<int>("UserId")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<long>("Timestamp")
.HasColumnType("bigint");
b.HasKey("UserId");
b.ToTable("LastMatches");
});
modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Profiles.Location", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<int>("X")
.HasColumnType("int");
b.Property<int>("Y")
.HasColumnType("int");
b.HasKey("Id");
b.ToTable("Locations");
});
modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Score", b =>
{
b.Property<int>("ScoreId")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<string>("PlayerIdCollection")
.HasColumnType("longtext");
b.Property<int>("Points")
.HasColumnType("int");
b.Property<int>("SlotId")
.HasColumnType("int");
b.Property<int>("Type")
.HasColumnType("int");
b.HasKey("ScoreId");
b.HasIndex("SlotId");
b.ToTable("Scores");
});
modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Token", b =>
{
b.Property<int>("TokenId")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<int>("GameVersion")
.HasColumnType("int");
b.Property<int>("UserId")
.HasColumnType("int");
b.Property<string>("UserLocation")
.HasColumnType("longtext");
b.Property<string>("UserToken")
.HasColumnType("longtext");
b.HasKey("TokenId");
b.ToTable("Tokens");
});
modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.User", b =>
{
b.Property<int>("UserId")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<string>("Biography")
.HasColumnType("longtext");
b.Property<string>("BooHash")
.HasColumnType("longtext");
b.Property<int>("Game")
.HasColumnType("int");
b.Property<string>("IconHash")
.HasColumnType("longtext");
b.Property<int>("LocationId")
.HasColumnType("int");
b.Property<string>("Pins")
.HasColumnType("longtext");
b.Property<string>("PlanetHash")
.HasColumnType("longtext");
b.Property<int>("StaffChallengeBronzeCount")
.HasColumnType("int");
b.Property<int>("StaffChallengeGoldCount")
.HasColumnType("int");
b.Property<int>("StaffChallengeSilverCount")
.HasColumnType("int");
b.Property<string>("Username")
.HasColumnType("longtext");
b.Property<string>("YayHash")
.HasColumnType("longtext");
b.HasKey("UserId");
b.HasIndex("LocationId");
b.ToTable("Users");
});
modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.HeartedProfile", b =>
{
b.HasOne("LBPUnion.ProjectLighthouse.Types.User", "HeartedUser")
.WithMany()
.HasForeignKey("HeartedUserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("LBPUnion.ProjectLighthouse.Types.User", "User")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("HeartedUser");
b.Navigation("User");
});
modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Levels.HeartedLevel", b =>
{
b.HasOne("LBPUnion.ProjectLighthouse.Types.Levels.Slot", "Slot")
.WithMany()
.HasForeignKey("SlotId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("LBPUnion.ProjectLighthouse.Types.User", "User")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Slot");
b.Navigation("User");
});
modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Levels.QueuedLevel", b =>
{
b.HasOne("LBPUnion.ProjectLighthouse.Types.Levels.Slot", "Slot")
.WithMany()
.HasForeignKey("SlotId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("LBPUnion.ProjectLighthouse.Types.User", "User")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Slot");
b.Navigation("User");
});
modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Levels.RatedLevel", b =>
{
b.HasOne("LBPUnion.ProjectLighthouse.Types.Levels.Slot", "Slot")
.WithMany()
.HasForeignKey("SlotId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("LBPUnion.ProjectLighthouse.Types.User", "User")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Slot");
b.Navigation("User");
});
modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Levels.Slot", b =>
{
b.HasOne("LBPUnion.ProjectLighthouse.Types.User", "Creator")
.WithMany()
.HasForeignKey("CreatorId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("LBPUnion.ProjectLighthouse.Types.Profiles.Location", "Location")
.WithMany()
.HasForeignKey("LocationId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Creator");
b.Navigation("Location");
});
modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Levels.VisitedLevel", b =>
{
b.HasOne("LBPUnion.ProjectLighthouse.Types.Levels.Slot", "Slot")
.WithMany()
.HasForeignKey("SlotId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("LBPUnion.ProjectLighthouse.Types.User", "User")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Slot");
b.Navigation("User");
});
modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Photo", b =>
{
b.HasOne("LBPUnion.ProjectLighthouse.Types.User", "Creator")
.WithMany()
.HasForeignKey("CreatorId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Creator");
});
modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.PhotoSubject", b =>
{
b.HasOne("LBPUnion.ProjectLighthouse.Types.User", "User")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Profiles.Comment", b =>
{
b.HasOne("LBPUnion.ProjectLighthouse.Types.User", "Poster")
.WithMany()
.HasForeignKey("PosterUserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("LBPUnion.ProjectLighthouse.Types.User", "Target")
.WithMany()
.HasForeignKey("TargetUserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Poster");
b.Navigation("Target");
});
modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.Score", b =>
{
b.HasOne("LBPUnion.ProjectLighthouse.Types.Levels.Slot", "Slot")
.WithMany()
.HasForeignKey("SlotId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Slot");
});
modelBuilder.Entity("LBPUnion.ProjectLighthouse.Types.User", b =>
{
b.HasOne("LBPUnion.ProjectLighthouse.Types.Profiles.Location", "Location")
.WithMany()
.HasForeignKey("LocationId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Location");
});
#pragma warning restore 612, 618
}
}
}

View file

@ -0,0 +1,24 @@
using Microsoft.EntityFrameworkCore.Migrations;
namespace ProjectLighthouse.Migrations
{
public partial class AddUserLocationToToken : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "UserLocation",
table: "Tokens",
type: "longtext",
nullable: true)
.Annotation("MySql:CharSet", "utf8mb4");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "UserLocation",
table: "Tokens");
}
}
}

View file

@ -394,6 +394,9 @@ namespace ProjectLighthouse.Migrations
b.Property<int>("UserId") b.Property<int>("UserId")
.HasColumnType("int"); .HasColumnType("int");
b.Property<string>("UserLocation")
.HasColumnType("longtext");
b.Property<string>("UserToken") b.Property<string>("UserToken")
.HasColumnType("longtext"); .HasColumnType("longtext");

View file

@ -2,7 +2,7 @@
<PropertyGroup> <PropertyGroup>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS> <DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<TargetFrameworks>net5.0;net6.0</TargetFrameworks> <TargetFramework>net6.0</TargetFramework>
<AssemblyName>LBPUnion.ProjectLighthouse</AssemblyName> <AssemblyName>LBPUnion.ProjectLighthouse</AssemblyName>
<RootNamespace>LBPUnion.ProjectLighthouse</RootNamespace> <RootNamespace>LBPUnion.ProjectLighthouse</RootNamespace>
</PropertyGroup> </PropertyGroup>

View file

@ -0,0 +1,13 @@
using Microsoft.AspNetCore.Mvc.Formatters;
namespace LBPUnion.ProjectLighthouse.Serialization
{
public class JsonOutputFormatter : StringOutputFormatter
{
public JsonOutputFormatter()
{
this.SupportedMediaTypes.Add("text/json");
this.SupportedMediaTypes.Add("application/json");
}
}
}

View file

@ -8,6 +8,7 @@ using LBPUnion.ProjectLighthouse.Serialization;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
@ -29,9 +30,24 @@ namespace LBPUnion.ProjectLighthouse
{ {
services.AddControllers(); services.AddControllers();
services.AddMvc(options => options.OutputFormatters.Add(new XmlOutputFormatter())); services.AddMvc
(
options =>
{
options.OutputFormatters.Add(new XmlOutputFormatter());
options.OutputFormatters.Add(new JsonOutputFormatter());
}
);
services.AddDbContext<Database>(); services.AddDbContext<Database>();
services.Configure<ForwardedHeadersOptions>
(
options =>
{
options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
}
);
} }
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
@ -51,6 +67,8 @@ namespace LBPUnion.ProjectLighthouse
if (env.IsDevelopment()) app.UseDeveloperExceptionPage(); if (env.IsDevelopment()) app.UseDeveloperExceptionPage();
app.UseForwardedHeaders();
// Logs every request and the response to it // Logs every request and the response to it
// Example: "200, 13ms: GET /LITTLEBIGPLANETPS3_XML/news" // Example: "200, 13ms: GET /LITTLEBIGPLANETPS3_XML/news"
// Example: "404, 127ms: GET /asdasd?query=osucookiezi727ppbluezenithtopplayhdhr" // Example: "404, 127ms: GET /asdasd?query=osucookiezi727ppbluezenithtopplayhdhr"

View file

@ -9,7 +9,8 @@ namespace LBPUnion.ProjectLighthouse.Types.Files
Plan, // PLN, uploaded with levels Plan, // PLN, uploaded with levels
Voice, // VOP, voice data Voice, // VOP, voice data
Painting, // PTG, paintings Painting, // PTG, paintings
Jpeg, // JFIF / FIF, used in sticker switches Jpeg, // JFIF / FIF, used in sticker switches,
Png, // used in LBP Vita
Unknown, Unknown,
} }
} }

View file

@ -0,0 +1,13 @@
namespace LBPUnion.ProjectLighthouse.Types.Levels
{
public enum SlotType
{
Developer = 0,
User = 1,
Moon = 2,
Unknown = 3,
Unknown2 = 4,
Pod = 5,
DLC = 8,
}
}

View file

@ -9,16 +9,20 @@ namespace LBPUnion.ProjectLighthouse.Types.Match
{ {
//[CreateRoom,["Players":["LumaLivy"],"Reservations":["0"],"NAT":[2],"Slots":[[1,3]],"RoomState":0,"HostMood":1,"PassedNoJoinPoint":0,"Location":[0x7f000001],"Language":1,"BuildVersion":289,"Search":""]] //[CreateRoom,["Players":["LumaLivy"],"Reservations":["0"],"NAT":[2],"Slots":[[1,3]],"RoomState":0,"HostMood":1,"PassedNoJoinPoint":0,"Location":[0x7f000001],"Language":1,"BuildVersion":289,"Search":""]]
public List<string> Players { get; set; } public List<string> Players { get; set; }
public List<string> Reservations { get; set; } public List<string> Reservations { get; set; }
// v slot type, 1 = 2974 // v slot type, 1 = 2974
// "Slots":[[5,0]] // "Slots":[[5,0]]
// ^ slot id // ^ slot id
// no idea why this is an array, but we'll work with it i suppose // no idea why this is an array, but we'll work with it i suppose
public List<List<int>> Slots { get; set; } public List<List<int>> Slots { get; set; }
[JsonIgnore] [JsonIgnore]
public List<int> FirstSlot => this.Slots[0]; public IEnumerable<int> FirstSlot => this.Slots[0];
public List<int> NAT; public List<int> NAT;
public int RoomState; public RoomState RoomState;
public int HostMood; public int HostMood;
public int PassedNoJoinPoint; public int PassedNoJoinPoint;
public List<int> Location; public List<int> Location;

View file

@ -0,0 +1,5 @@
namespace LBPUnion.ProjectLighthouse.Types.Match
{
public class FindBestRoom : CreateRoom
{}
}

View file

@ -0,0 +1,18 @@
using System.Collections.Generic;
using System.Text.Json.Serialization;
namespace LBPUnion.ProjectLighthouse.Types.Match
{
public class FindBestRoomResponse
{
public List<Player> Players { get; set; }
public List<List<int>> Slots { get; set; }
[JsonIgnore]
public IEnumerable<int> FirstSlot => this.Slots[0];
[JsonPropertyName("Location")]
public List<string> Locations { get; set; }
}
}

View file

@ -0,0 +1,14 @@
using System;
using System.Text.Json.Serialization;
namespace LBPUnion.ProjectLighthouse.Types.Match
{
[Serializable]
public class Player
{
public string PlayerId { get; set; }
[JsonPropertyName("matching_res")]
public int MatchingRes { get; set; }
}
}

View file

@ -92,7 +92,7 @@ namespace LBPUnion.ProjectLighthouse.Types
LbpSerializer.StringElement("medium", this.MediumHash) + LbpSerializer.StringElement("medium", this.MediumHash) +
LbpSerializer.StringElement("large", this.LargeHash) + LbpSerializer.StringElement("large", this.LargeHash) +
LbpSerializer.StringElement("plan", this.PlanHash) + LbpSerializer.StringElement("plan", this.PlanHash) +
LbpSerializer.StringElement("author", this.CreatorId) + LbpSerializer.StringElement("author", this.Creator.Username) +
LbpSerializer.StringElement("subjects", subjectsAggregate) + LbpSerializer.StringElement("subjects", subjectsAggregate) +
slot; slot;

View file

@ -12,6 +12,8 @@ namespace LBPUnion.ProjectLighthouse.Types
public string UserToken { get; set; } public string UserToken { get; set; }
public string UserLocation { get; set; }
public GameVersion GameVersion { get; set; } public GameVersion GameVersion { get; set; }
} }
} }