Skip to content

Commit 41a2767

Browse files
authored
LBP3 Challenges (#987)
Implements the ability to have the server read and return the contents of a `ChallengeConfig.xml` file from the working directory to the game if requested. If no config file is found, the server will default to a hard-coded config which contains and attributes all 14 challenges. This closes #426. Score submission and fetching for challenges and adventures will come in a seperate PR.
2 parents 3cfc17d + e2cc862 commit 41a2767

5 files changed

Lines changed: 365 additions & 62 deletions

File tree

Refresh.Database/Models/Pins/ServerPins.cs

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
namespace Refresh.Database.Models.Pins;
22

33
/// <summary>
4-
/// The progress types of pins which have to be awarded manually by the server.
4+
/// The progress types of pins which have to either be awarded manually by the server,
5+
/// or be returned/used elsewhere (e.g. LBP3 challenges)
56
/// </summary>
67
public enum ServerPins : long
78
{
@@ -15,4 +16,47 @@ public enum ServerPins : long
1516
SignIntoWebsite = 2691148325,
1617
HeartPlayerOnWebsite = 1965011384,
1718
QueueLevelOnWebsite = 2833810997,
19+
20+
// LBP3 challenges
21+
OverLineLbp3ChallengeMedal = 3003874881,
22+
OverLineLbp3ChallengeRanking = 2922567456,
23+
24+
PixelPaceLbp3ChallengeMedal = 282407472,
25+
PixelPaceLbp3ChallengeRanking = 3340696069,
26+
27+
RabbitBoxingLbp3ChallengeMedal = 2529088759,
28+
RabbitBoxingLbp3ChallengeRanking = 958144818,
29+
30+
FloatyFluidLbp3ChallengeMedal = 183892581,
31+
FloatyFluidLbp3ChallengeRanking = 3442917932,
32+
33+
ToggleIslandLbp3ChallengeMedal = 315245769,
34+
ToggleIslandLbp3ChallengeRanking = 443310584,
35+
36+
SpaceDodgeballLbp3ChallengeMedal = 144212050,
37+
SpaceDodgeballLbp3ChallengeRanking = 2123417147,
38+
39+
InvisibleMazeLbp3ChallengeMedal = 249569175,
40+
InvisibleMazeLbp3ChallengeRanking = 1943114258,
41+
42+
HoverboardLbp3ChallengeMedal = 3478661003,
43+
HoverboardLbp3ChallengeRanking = 592022798,
44+
45+
WhoopTowerLbp3ChallengeMedal = 216730878,
46+
WhoopTowerLbp3ChallengeRanking = 545532447,
47+
48+
SwoopPanelsLbp3ChallengeMedal = 2054302637,
49+
SwoopPanelsLbp3ChallengeRanking = 3288689476,
50+
51+
PinballLbp3ChallengeMedal = 618998172,
52+
PinballLbp3ChallengeRanking = 4087839785,
53+
54+
TieSkipLbp3ChallengeMedal = 3953447125,
55+
TieSkipLbp3ChallengeRanking = 2556445436,
56+
57+
JokerLbp3ChallengeMedal = 1093784294,
58+
JokerLbp3ChallengeRanking = 1757295127,
59+
60+
CherryShooterLbp3ChallengeMedal = 1568570416,
61+
CherryShooterLbp3ChallengeRanking = 3721717765,
1862
}

Refresh.Interfaces.Game/Endpoints/Handshake/MetadataEndpoints.cs

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
using System.Xml.Serialization;
12
using Bunkum.Core;
23
using Bunkum.Core.Endpoints;
34
using Bunkum.Core.Endpoints.Debugging;
45
using Bunkum.Core.Responses;
6+
using Bunkum.Core.Responses.Serialization;
57
using Bunkum.Listener.Protocol;
68
using Bunkum.Protocols.Http;
79
using Refresh.Common.Time;
@@ -191,23 +193,48 @@ private static readonly Lazy<string?> DeveloperVideosFile
191193
// {"currentLevel": ["developer_adventure_planet", 349],"inStore": true,"participants": ["turecross321","","",""]}
192194
// {"highlightedSearchResult": ["level",811],"currentLevel": ["pod", 0],"inStore": true,"participants": ["turecross321","","",""]}
193195
public string GameState(RequestContext context) => "VALID";
196+
197+
private static readonly Lazy<string?> ChallengeConfigFile
198+
= new(() =>
199+
{
200+
string path = Path.Combine(Environment.CurrentDirectory, "ChallengeConfig.xml");
201+
202+
return File.Exists(path) ? File.ReadAllText(path) : null;
203+
});
194204

195205
[GameEndpoint("ChallengeConfig.xml", ContentType.Xml)]
196206
[MinimumRole(GameUserRole.Restricted)]
197-
public SerializedLbp3ChallengeList ChallengeConfig(RequestContext context, IDateTimeProvider timeProvider)
207+
public string ChallengeConfig(RequestContext context)
198208
{
199-
//TODO: allow this to be controlled by the server owner, right now lets just send the game 0 challenges,
200-
// so nothing appears in the challenges menu
201-
return new SerializedLbp3ChallengeList
209+
bool created = ChallengeConfigFile.IsValueCreated;
210+
string? challengeConfig = ChallengeConfigFile.Value;
211+
212+
// If file was read, return its contents. Else serialize and return a hard-coded default list of challenges.
213+
if (challengeConfig != null)
202214
{
203-
TotalChallenges = 0,
204-
EndTime = (ulong)(timeProvider.Now.ToUnixTimeMilliseconds() * 1000),
205-
BronzeRankPercentage = 0,
206-
SilverRankPercentage = 0,
207-
GoldRankPercentage = 0,
208-
CycleTime = 0,
209-
Challenges = [],
210-
};
215+
return challengeConfig;
216+
}
217+
else
218+
{
219+
// Only log this warning once
220+
if (!created) context.Logger.LogWarning(BunkumCategory.Request,
221+
"ChallengeConfig.xml file is missing! We've defaulted to one which is loosely based off of the official server's config, "+
222+
"but it might be relevant to you if you are an advanced user.");
223+
224+
using MemoryStream ms = new();
225+
using BunkumXmlTextWriter bunkumXmlTextWriter = new(ms);
226+
227+
XmlSerializerNamespaces namespaces = new();
228+
namespaces.Add("", "");
229+
230+
XmlSerializer serializer = new(typeof(SerializedLbp3ChallengeList));
231+
serializer.Serialize(bunkumXmlTextWriter, SerializedLbp3ChallengeList.Default, namespaces);
232+
233+
ms.Seek(0, SeekOrigin.Begin);
234+
using StreamReader reader = new(ms);
235+
236+
return reader.ReadToEnd();
237+
}
211238
}
212239

213240
[GameEndpoint("tags")]

Refresh.Interfaces.Game/Types/Challenges/Lbp3/SerializedLevelChallenge.cs renamed to Refresh.Interfaces.Game/Types/Challenges/Lbp3/SerializedLbp3Challenge.cs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,20 @@ public class SerializedLbp3Challenge
3737
public string LamsTitleId { get; set; }
3838

3939
/// <summary>
40-
/// The ID of the pin you receive for completing this challenge
40+
/// The progress type of the pin indicating whether the user's highscore is bronze, silver or gold (progress value is 1-3 accordingly)
4141
/// </summary>
4242
[XmlAttribute("Challenge_PinId")]
43-
public ulong PinId { get; set; }
43+
public ulong ScoreMedalPinProgressType { get; set; }
4444

45+
/// <summary>
46+
/// The progress type of the Pin indicating whether the user is in the top 50%, 25% or 10% of the leaderboard
47+
/// </summary>
48+
// TODO: As soon as score submission for adventures/LBP3 challenges is implemented,
49+
// find out whether these need to be awarded by the server, and also find out
50+
// whether these pins have a descending progress and special case them
51+
// in the progress update method if they do.
4552
[XmlAttribute("Challenge_RankPin")]
46-
public ulong RankPin { get; set; }
53+
public ulong ScoreRankingPinProgressType { get; set; }
4754

4855
/// <summary>
4956
/// A PSN DLC id for the DLC associated with this challenge

0 commit comments

Comments
 (0)