rework achievements system + minor cleanup

rework achievements system:
    - support for Achievements page in journal
    - register achievement tasks in database to avoid duplicate rewards and to register progress (achievement levels)
    - better achievement tasks xml database (for multiple games)
    - support for older games SetUserAchievementTask (V1)
    - add some missed achievement IDs
    - move achievement data to Resources/achievements/

additionally:
    - add mmo zones for MaM and some additional mmo zones for EMD
    - move missions Resources into Resources/missions/
    - split SoD/MaM missions into separte files
    - move rank data to Resources/ranks/
    - cleanup sodoff.csproj

SQLite database schema changes:

```
CREATE TABLE "AchievementTaskState" (
	"VikingId"	INTEGER NOT NULL,
	"TaskId"	INTEGER NOT NULL,
	"Points"	INTEGER NOT NULL,
	CONSTRAINT "PK_AchievementTaskState" PRIMARY KEY("TaskId","VikingId"),
	CONSTRAINT "FK_AchievementTaskState_Vikings_VikingId" FOREIGN KEY("VikingId") REFERENCES "Vikings"("Id") ON DELETE CASCADE
);
```
This commit is contained in:
Robert Paciorek 2025-02-08 09:26:38 +00:00
parent 24695583b3
commit 13df822608
39 changed files with 141145 additions and 43769 deletions

View File

@ -11,9 +11,12 @@ namespace sodoff.Controllers.Common;
public class AchievementController : Controller {
public readonly DBContext ctx;
private AchievementStoreSingleton achievementStore;
private AchievementService achievementService;
public AchievementController(DBContext ctx, AchievementService achievementService) {
public AchievementController(DBContext ctx, AchievementStoreSingleton achievementStore, AchievementService achievementService) {
this.ctx = ctx;
this.achievementStore = achievementStore;
this.achievementService = achievementService;
}
@ -42,19 +45,26 @@ public class AchievementController : Controller {
public IActionResult GetAllRanks([FromForm] string apiKey) {
uint gameVersion = ClientVersion.GetVersion(apiKey);
if (gameVersion <= ClientVersion.Max_OldJS && (gameVersion & ClientVersion.WoJS) != 0)
return Ok(XmlUtil.ReadResourceXmlString("allranks_wojs"));
else if (gameVersion == ClientVersion.MB)
return Ok(XmlUtil.ReadResourceXmlString("allranks_mb"));
// TODO, this is a placeholder
return Ok(XmlUtil.ReadResourceXmlString("allranks"));
return Ok(XmlUtil.ReadResourceXmlString("ranks.allranks_wojs"));
if (gameVersion == ClientVersion.MB)
return Ok(XmlUtil.ReadResourceXmlString("ranks.allranks_mb"));
return Ok(XmlUtil.ReadResourceXmlString("ranks.allranks_sod"));
}
[HttpPost]
//[Produces("application/xml")]
[Produces("application/xml")]
[Route("AchievementWebService.asmx/GetAchievementTaskInfo")]
public IActionResult GetAchievementTaskInfo() {
// TODO
return Ok(XmlUtil.ReadResourceXmlString("achievementtaskinfo"));
public IActionResult GetAchievementTaskInfo([FromForm] string achievementTaskIDList, [FromForm] string apiKey) {
int[] achievementTaskIDs = XmlUtil.DeserializeXml<int[]>(achievementTaskIDList);
List<AchievementTaskInfo> achievementTaskInfos = new();
foreach (int taskId in achievementTaskIDs) {
var achievementInfo = achievementStore.GetAllAchievementTaskInfo(taskId, ClientVersion.GetVersion(apiKey));
if (achievementInfo != null)
achievementTaskInfos.AddRange(achievementInfo);
}
return Ok(new ArrayOfAchievementTaskInfo {
AchievementTaskInfo = achievementTaskInfos.ToArray()
});
}
[HttpPost]
@ -89,7 +99,6 @@ public class AchievementController : Controller {
}
AchievementPointTypes xpType = (AchievementPointTypes)type;
// TODO: we allow set currencies here, do we want this?
achievementService.SetAchievementPoints(viking, xpType, value);
ctx.SaveChanges();
return Ok("OK");
@ -146,8 +155,8 @@ public class AchievementController : Controller {
ArrayOfUserAchievementInfo arrAchievements = new ArrayOfUserAchievementInfo {
UserAchievementInfo = new UserAchievementInfo[]{
achievementService.CreateUserAchievementInfo(viking, AchievementPointTypes.PlayerXP),
achievementService.CreateUserAchievementInfo(viking.Uid, 60000, AchievementPointTypes.PlayerFarmingXP), // TODO: placeholder until there is no leveling for farm XP
achievementService.CreateUserAchievementInfo(viking.Uid, 20000, AchievementPointTypes.PlayerFishingXP), // TODO: placeholder until there is no leveling for fishing XP
achievementService.CreateUserAchievementInfo(viking, AchievementPointTypes.PlayerFarmingXP),
achievementService.CreateUserAchievementInfo(viking, AchievementPointTypes.PlayerFishingXP),
}
};
@ -171,22 +180,13 @@ public class AchievementController : Controller {
[Route("V2/AchievementWebService.asmx/SetUserAchievementTask")]
[DecryptRequest("achievementTaskSetRequest")]
[VikingSession(UseLock=true)]
public IActionResult SetUserAchievementTask(Viking viking) {
public IActionResult SetUserAchievementTask(Viking viking, [FromForm] string apiKey) {
AchievementTaskSetRequest request = XmlUtil.DeserializeXml<AchievementTaskSetRequest>(Request.Form["achievementTaskSetRequest"]);
var response = new List<AchievementTaskSetResponse>();
foreach (var task in request.AchievementTaskSet) {
response.Add(
new AchievementTaskSetResponse {
Success = true,
UserMessage = true, // TODO: placeholder
AchievementName = "Placeholder Achievement", // TODO: placeholder
Level = 1, // TODO: placeholder
AchievementTaskGroupID = 1279, // TODO: placeholder
LastLevelCompleted = true, // TODO: placeholder
AchievementInfoID = 1279, // TODO: placeholder
AchievementRewards = achievementService.ApplyAchievementRewardsByTask(viking, task)
}
achievementService.ApplyAchievementRewardsByTask(viking, task.TaskID, ClientVersion.GetVersion(apiKey))
);
}
ctx.SaveChanges();
@ -194,6 +194,38 @@ public class AchievementController : Controller {
return Ok(new ArrayOfAchievementTaskSetResponse { AchievementTaskSetResponse = response.ToArray() });
}
[HttpPost]
[Produces("application/xml")]
[Route("AchievementWebService.asmx/SetUserAchievementTask")] // used by World Of Jumpstart
[VikingSession(UseLock=true)]
public IActionResult SetUserAchievementTaskV1(Viking viking, [FromForm] int taskID, [FromForm] string apiKey) {
var response = achievementService.ApplyAchievementRewardsByTask(viking, taskID, ClientVersion.GetVersion(apiKey));
ctx.SaveChanges();
return Ok(response);
}
[HttpPost]
[Produces("application/xml")]
[Route("AchievementWebService.asmx/GetUserAchievementTask")]
// [VikingSession]
public IActionResult GetUserAchievementTask([FromForm] string userId, [FromForm] string apiKey) {
Viking? viking = ctx.Vikings.FirstOrDefault(e => e.Uid == Guid.Parse(userId));
if (viking is null)
return Ok(new ArrayOfUserAchievementTask());
return Ok(new ArrayOfUserAchievementTask {
UserAchievementTask = achievementService.GetUserAchievementTask(viking, ClientVersion.GetVersion(apiKey))
});
}
[HttpPost]
[Produces("application/xml")]
[Route("V2/AchievementWebService.asmx/GetUserAchievementTaskRedeemableRewards")]
// [VikingSession]
public IActionResult GetUserAchievementTaskRedeemableRewards() {
return Ok(); // TODO: this should be <UATRRS>
}
[HttpPost]
[Produces("application/xml")]
[Route("AchievementWebService.asmx/ApplyPayout")]

View File

@ -59,9 +59,9 @@ public class ItemStoreController : Controller {
public IActionResult GetRankAttributeData([FromForm] string apiKey) {
uint gameVersion = ClientVersion.GetVersion(apiKey);
if (gameVersion == ClientVersion.MB)
return Ok(XmlUtil.ReadResourceXmlString("rankattrib_mb"));
return Ok(XmlUtil.ReadResourceXmlString("ranks.rankattrib_mb"));
// TODO, this is a placeholder
return Ok(XmlUtil.ReadResourceXmlString("rankattrib"));
return Ok(XmlUtil.ReadResourceXmlString("ranks.rankattrib"));
}
[Route("ItemStoreWebService.asmx/GetAssetVersions")]

View File

@ -0,0 +1,15 @@
using System.ComponentModel.DataAnnotations;
using Microsoft.EntityFrameworkCore;
namespace sodoff.Model;
[PrimaryKey(nameof(TaskId), nameof(VikingId))]
public class AchievementTaskState {
public int VikingId { get; set; }
public int TaskId { get; set; }
public int Points { get; set; }
public virtual Viking? Viking { get; set; }
}

View File

@ -117,6 +117,9 @@ public class DBContext : DbContext {
builder.Entity<Viking>().HasMany(v => v.TaskStatuses)
.WithOne(e => e.Viking);
builder.Entity<Viking>().HasMany(v => v.AchievementTaskStates)
.WithOne(e => e.Viking);
builder.Entity<Viking>().HasOne(v => v.SelectedDragon)
.WithOne()
.HasForeignKey<Viking>(e => e.SelectedDragonId);
@ -227,6 +230,10 @@ public class DBContext : DbContext {
.WithMany(e => e.MissionStates)
.HasForeignKey(e => e.VikingId);
builder.Entity<AchievementTaskState>().HasOne(m => m.Viking)
.WithMany(e => e.AchievementTaskStates)
.HasForeignKey(e => e.VikingId);
builder.Entity<AchievementPoints>().HasKey(e => new { e.VikingId, e.Type });
builder.Entity<AchievementPoints>()

View File

@ -27,6 +27,7 @@ public class Viking {
public virtual ICollection<Image> Images { get; set; } = null!;
public virtual ICollection<MissionState> MissionStates { get; set; } = null!;
public virtual ICollection<TaskStatus> TaskStatuses { get; set; } = null!;
public virtual ICollection<AchievementTaskState> AchievementTaskStates { get; set; } = null!;
public virtual ICollection<Room> Rooms { get; set; } = null!;
public virtual ICollection<SceneData> SceneData { get; set; } = null!;
public virtual ICollection<AchievementPoints> AchievementPoints { get; set; } = null!;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,843 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<ArrayOfAchievementTaskInfo xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://api.jumpstart.com/">
<AchievementTaskInfo>
<AchievementInfoID>12418</AchievementInfoID>
<AchievementTaskID>2471</AchievementTaskID>
<AchievementTaskGroupID>2418</AchievementTaskGroupID>
<AchievementTaskGroupName>Thawfest 2023 Event Rewards</AchievementTaskGroupName>
<Level>1</Level>
<MessageID>0</MessageID>
<PointValue>50</PointValue>
<Reproducible>false</Reproducible>
<AllowNonMembers>true</AllowNonMembers>
<Distinct>false</Distinct>
<ProductGroupID>9</ProductGroupID>
<TaskEvent_Points>1</TaskEvent_Points>
<Cumulative>true</Cumulative>
<PreredeemMessageID>0</PreredeemMessageID>
<ValidityFromDate>2023-02-01T00:00:00</ValidityFromDate>
<ValidityToDate>2023-06-07T19:00:00</ValidityToDate>
<isBeyondLevelAllowed>false</isBeyondLevelAllowed>
<VisibilityFromDate>2023-02-01T00:00:00</VisibilityFromDate>
<VisibilityToDate>2023-06-07T19:00:00</VisibilityToDate>
</AchievementTaskInfo>
<AchievementTaskInfo>
<AchievementInfoID>12419</AchievementInfoID>
<AchievementTaskID>2471</AchievementTaskID>
<AchievementTaskGroupID>2418</AchievementTaskGroupID>
<AchievementTaskGroupName>Thawfest 2023 Event Rewards</AchievementTaskGroupName>
<Level>2</Level>
<MessageID>0</MessageID>
<PointValue>100</PointValue>
<Reproducible>false</Reproducible>
<AllowNonMembers>true</AllowNonMembers>
<Distinct>false</Distinct>
<ProductGroupID>9</ProductGroupID>
<TaskEvent_Points>1</TaskEvent_Points>
<Cumulative>true</Cumulative>
<PreredeemMessageID>0</PreredeemMessageID>
<ValidityFromDate>2023-02-01T00:00:00</ValidityFromDate>
<ValidityToDate>2023-06-07T19:00:00</ValidityToDate>
<isBeyondLevelAllowed>false</isBeyondLevelAllowed>
<VisibilityFromDate>2023-02-01T00:00:00</VisibilityFromDate>
<VisibilityToDate>2023-06-07T19:00:00</VisibilityToDate>
</AchievementTaskInfo>
<AchievementTaskInfo>
<AchievementInfoID>12420</AchievementInfoID>
<AchievementTaskID>2471</AchievementTaskID>
<AchievementTaskGroupID>2418</AchievementTaskGroupID>
<AchievementTaskGroupName>Thawfest 2023 Event Rewards</AchievementTaskGroupName>
<Level>3</Level>
<MessageID>0</MessageID>
<PointValue>150</PointValue>
<Reproducible>false</Reproducible>
<AllowNonMembers>true</AllowNonMembers>
<Distinct>false</Distinct>
<ProductGroupID>9</ProductGroupID>
<TaskEvent_Points>1</TaskEvent_Points>
<Cumulative>true</Cumulative>
<PreredeemMessageID>0</PreredeemMessageID>
<ValidityFromDate>2023-02-01T00:00:00</ValidityFromDate>
<ValidityToDate>2023-06-07T19:00:00</ValidityToDate>
<isBeyondLevelAllowed>false</isBeyondLevelAllowed>
<VisibilityFromDate>2023-02-01T00:00:00</VisibilityFromDate>
<VisibilityToDate>2023-06-07T19:00:00</VisibilityToDate>
</AchievementTaskInfo>
<AchievementTaskInfo>
<AchievementInfoID>12421</AchievementInfoID>
<AchievementTaskID>2471</AchievementTaskID>
<AchievementTaskGroupID>2418</AchievementTaskGroupID>
<AchievementTaskGroupName>Thawfest 2023 Event Rewards</AchievementTaskGroupName>
<Level>4</Level>
<MessageID>0</MessageID>
<PointValue>200</PointValue>
<Reproducible>false</Reproducible>
<AllowNonMembers>true</AllowNonMembers>
<Distinct>false</Distinct>
<ProductGroupID>9</ProductGroupID>
<TaskEvent_Points>1</TaskEvent_Points>
<Cumulative>true</Cumulative>
<PreredeemMessageID>0</PreredeemMessageID>
<ValidityFromDate>2023-02-01T00:00:00</ValidityFromDate>
<ValidityToDate>2023-06-07T19:00:00</ValidityToDate>
<isBeyondLevelAllowed>false</isBeyondLevelAllowed>
<VisibilityFromDate>2023-02-01T00:00:00</VisibilityFromDate>
<VisibilityToDate>2023-06-07T19:00:00</VisibilityToDate>
</AchievementTaskInfo>
<AchievementTaskInfo>
<AchievementInfoID>12422</AchievementInfoID>
<AchievementTaskID>2471</AchievementTaskID>
<AchievementTaskGroupID>2418</AchievementTaskGroupID>
<AchievementTaskGroupName>Thawfest 2023 Event Rewards</AchievementTaskGroupName>
<Level>5</Level>
<MessageID>0</MessageID>
<PointValue>300</PointValue>
<Reproducible>false</Reproducible>
<AllowNonMembers>true</AllowNonMembers>
<Distinct>false</Distinct>
<ProductGroupID>9</ProductGroupID>
<TaskEvent_Points>1</TaskEvent_Points>
<Cumulative>true</Cumulative>
<PreredeemMessageID>0</PreredeemMessageID>
<ValidityFromDate>2023-02-01T00:00:00</ValidityFromDate>
<ValidityToDate>2023-06-07T19:00:00</ValidityToDate>
<isBeyondLevelAllowed>false</isBeyondLevelAllowed>
<VisibilityFromDate>2023-02-01T00:00:00</VisibilityFromDate>
<VisibilityToDate>2023-06-07T19:00:00</VisibilityToDate>
</AchievementTaskInfo>
<AchievementTaskInfo>
<AchievementInfoID>12423</AchievementInfoID>
<AchievementTaskID>2471</AchievementTaskID>
<AchievementTaskGroupID>2418</AchievementTaskGroupID>
<AchievementTaskGroupName>Thawfest 2023 Event Rewards</AchievementTaskGroupName>
<Level>6</Level>
<MessageID>0</MessageID>
<PointValue>400</PointValue>
<Reproducible>false</Reproducible>
<AllowNonMembers>true</AllowNonMembers>
<Distinct>false</Distinct>
<ProductGroupID>9</ProductGroupID>
<TaskEvent_Points>1</TaskEvent_Points>
<Cumulative>true</Cumulative>
<PreredeemMessageID>0</PreredeemMessageID>
<ValidityFromDate>2023-02-01T00:00:00</ValidityFromDate>
<ValidityToDate>2023-06-07T19:00:00</ValidityToDate>
<isBeyondLevelAllowed>false</isBeyondLevelAllowed>
<VisibilityFromDate>2023-02-01T00:00:00</VisibilityFromDate>
<VisibilityToDate>2023-06-07T19:00:00</VisibilityToDate>
</AchievementTaskInfo>
<AchievementTaskInfo>
<AchievementInfoID>12424</AchievementInfoID>
<AchievementTaskID>2471</AchievementTaskID>
<AchievementTaskGroupID>2418</AchievementTaskGroupID>
<AchievementTaskGroupName>Thawfest 2023 Event Rewards</AchievementTaskGroupName>
<Level>7</Level>
<MessageID>0</MessageID>
<PointValue>500</PointValue>
<Reproducible>false</Reproducible>
<AllowNonMembers>true</AllowNonMembers>
<Distinct>false</Distinct>
<ProductGroupID>9</ProductGroupID>
<TaskEvent_Points>1</TaskEvent_Points>
<Cumulative>true</Cumulative>
<PreredeemMessageID>0</PreredeemMessageID>
<ValidityFromDate>2023-02-01T00:00:00</ValidityFromDate>
<ValidityToDate>2023-06-07T19:00:00</ValidityToDate>
<isBeyondLevelAllowed>false</isBeyondLevelAllowed>
<VisibilityFromDate>2023-02-01T00:00:00</VisibilityFromDate>
<VisibilityToDate>2023-06-07T19:00:00</VisibilityToDate>
</AchievementTaskInfo>
<AchievementTaskInfo>
<AchievementInfoID>12425</AchievementInfoID>
<AchievementTaskID>2471</AchievementTaskID>
<AchievementTaskGroupID>2418</AchievementTaskGroupID>
<AchievementTaskGroupName>Thawfest 2023 Event Rewards</AchievementTaskGroupName>
<Level>8</Level>
<MessageID>0</MessageID>
<PointValue>600</PointValue>
<Reproducible>false</Reproducible>
<AllowNonMembers>true</AllowNonMembers>
<Distinct>false</Distinct>
<ProductGroupID>9</ProductGroupID>
<TaskEvent_Points>1</TaskEvent_Points>
<Cumulative>true</Cumulative>
<PreredeemMessageID>0</PreredeemMessageID>
<ValidityFromDate>2023-02-01T00:00:00</ValidityFromDate>
<ValidityToDate>2023-06-07T19:00:00</ValidityToDate>
<isBeyondLevelAllowed>false</isBeyondLevelAllowed>
<VisibilityFromDate>2023-02-01T00:00:00</VisibilityFromDate>
<VisibilityToDate>2023-06-07T19:00:00</VisibilityToDate>
</AchievementTaskInfo>
<AchievementTaskInfo>
<AchievementInfoID>12426</AchievementInfoID>
<AchievementTaskID>2471</AchievementTaskID>
<AchievementTaskGroupID>2418</AchievementTaskGroupID>
<AchievementTaskGroupName>Thawfest 2023 Event Rewards</AchievementTaskGroupName>
<Level>9</Level>
<MessageID>0</MessageID>
<PointValue>700</PointValue>
<Reproducible>false</Reproducible>
<AllowNonMembers>true</AllowNonMembers>
<Distinct>false</Distinct>
<ProductGroupID>9</ProductGroupID>
<TaskEvent_Points>1</TaskEvent_Points>
<Cumulative>true</Cumulative>
<PreredeemMessageID>0</PreredeemMessageID>
<ValidityFromDate>2023-02-01T00:00:00</ValidityFromDate>
<ValidityToDate>2023-06-07T19:00:00</ValidityToDate>
<isBeyondLevelAllowed>false</isBeyondLevelAllowed>
<VisibilityFromDate>2023-02-01T00:00:00</VisibilityFromDate>
<VisibilityToDate>2023-06-07T19:00:00</VisibilityToDate>
</AchievementTaskInfo>
<AchievementTaskInfo>
<AchievementInfoID>12427</AchievementInfoID>
<AchievementTaskID>2471</AchievementTaskID>
<AchievementTaskGroupID>2418</AchievementTaskGroupID>
<AchievementTaskGroupName>Thawfest 2023 Event Rewards</AchievementTaskGroupName>
<Level>10</Level>
<MessageID>0</MessageID>
<PointValue>800</PointValue>
<Reproducible>false</Reproducible>
<AllowNonMembers>true</AllowNonMembers>
<Distinct>false</Distinct>
<ProductGroupID>9</ProductGroupID>
<TaskEvent_Points>1</TaskEvent_Points>
<Cumulative>true</Cumulative>
<PreredeemMessageID>0</PreredeemMessageID>
<ValidityFromDate>2023-02-01T00:00:00</ValidityFromDate>
<ValidityToDate>2023-06-07T19:00:00</ValidityToDate>
<isBeyondLevelAllowed>false</isBeyondLevelAllowed>
<VisibilityFromDate>2023-02-01T00:00:00</VisibilityFromDate>
<VisibilityToDate>2023-06-07T19:00:00</VisibilityToDate>
</AchievementTaskInfo>
<AchievementTaskInfo>
<AchievementInfoID>12428</AchievementInfoID>
<AchievementTaskID>2471</AchievementTaskID>
<AchievementTaskGroupID>2418</AchievementTaskGroupID>
<AchievementTaskGroupName>Thawfest 2023 Event Rewards</AchievementTaskGroupName>
<Level>11</Level>
<MessageID>0</MessageID>
<PointValue>900</PointValue>
<Reproducible>false</Reproducible>
<AllowNonMembers>true</AllowNonMembers>
<Distinct>false</Distinct>
<ProductGroupID>9</ProductGroupID>
<TaskEvent_Points>1</TaskEvent_Points>
<Cumulative>true</Cumulative>
<PreredeemMessageID>0</PreredeemMessageID>
<ValidityFromDate>2023-02-01T00:00:00</ValidityFromDate>
<ValidityToDate>2023-06-07T19:00:00</ValidityToDate>
<isBeyondLevelAllowed>false</isBeyondLevelAllowed>
<VisibilityFromDate>2023-02-01T00:00:00</VisibilityFromDate>
<VisibilityToDate>2023-06-07T19:00:00</VisibilityToDate>
</AchievementTaskInfo>
<AchievementTaskInfo>
<AchievementInfoID>12429</AchievementInfoID>
<AchievementTaskID>2471</AchievementTaskID>
<AchievementTaskGroupID>2418</AchievementTaskGroupID>
<AchievementTaskGroupName>Thawfest 2023 Event Rewards</AchievementTaskGroupName>
<Level>12</Level>
<MessageID>0</MessageID>
<PointValue>1000</PointValue>
<Reproducible>false</Reproducible>
<AllowNonMembers>true</AllowNonMembers>
<Distinct>false</Distinct>
<ProductGroupID>9</ProductGroupID>
<TaskEvent_Points>1</TaskEvent_Points>
<Cumulative>true</Cumulative>
<PreredeemMessageID>0</PreredeemMessageID>
<ValidityFromDate>2023-02-01T00:00:00</ValidityFromDate>
<ValidityToDate>2023-06-07T19:00:00</ValidityToDate>
<isBeyondLevelAllowed>false</isBeyondLevelAllowed>
<VisibilityFromDate>2023-02-01T00:00:00</VisibilityFromDate>
<VisibilityToDate>2023-06-07T19:00:00</VisibilityToDate>
</AchievementTaskInfo>
<AchievementTaskInfo>
<AchievementInfoID>12430</AchievementInfoID>
<AchievementTaskID>2471</AchievementTaskID>
<AchievementTaskGroupID>2418</AchievementTaskGroupID>
<AchievementTaskGroupName>Thawfest 2023 Event Rewards</AchievementTaskGroupName>
<Level>13</Level>
<MessageID>0</MessageID>
<PointValue>1500</PointValue>
<Reproducible>false</Reproducible>
<AllowNonMembers>true</AllowNonMembers>
<Distinct>false</Distinct>
<ProductGroupID>9</ProductGroupID>
<TaskEvent_Points>1</TaskEvent_Points>
<Cumulative>true</Cumulative>
<PreredeemMessageID>0</PreredeemMessageID>
<ValidityFromDate>2023-02-01T00:00:00</ValidityFromDate>
<ValidityToDate>2023-06-07T19:00:00</ValidityToDate>
<isBeyondLevelAllowed>false</isBeyondLevelAllowed>
<VisibilityFromDate>2023-02-01T00:00:00</VisibilityFromDate>
<VisibilityToDate>2023-06-07T19:00:00</VisibilityToDate>
</AchievementTaskInfo>
<AchievementTaskInfo>
<AchievementInfoID>12431</AchievementInfoID>
<AchievementTaskID>2471</AchievementTaskID>
<AchievementTaskGroupID>2418</AchievementTaskGroupID>
<AchievementTaskGroupName>Thawfest 2023 Event Rewards</AchievementTaskGroupName>
<Level>14</Level>
<MessageID>0</MessageID>
<PointValue>2000</PointValue>
<Reproducible>false</Reproducible>
<AllowNonMembers>true</AllowNonMembers>
<Distinct>false</Distinct>
<ProductGroupID>9</ProductGroupID>
<TaskEvent_Points>1</TaskEvent_Points>
<Cumulative>true</Cumulative>
<PreredeemMessageID>0</PreredeemMessageID>
<ValidityFromDate>2023-02-01T00:00:00</ValidityFromDate>
<ValidityToDate>2023-06-07T19:00:00</ValidityToDate>
<isBeyondLevelAllowed>false</isBeyondLevelAllowed>
<VisibilityFromDate>2023-02-01T00:00:00</VisibilityFromDate>
<VisibilityToDate>2023-06-07T19:00:00</VisibilityToDate>
</AchievementTaskInfo>
<AchievementTaskInfo>
<AchievementInfoID>12432</AchievementInfoID>
<AchievementTaskID>2471</AchievementTaskID>
<AchievementTaskGroupID>2418</AchievementTaskGroupID>
<AchievementTaskGroupName>Thawfest 2023 Event Rewards</AchievementTaskGroupName>
<Level>15</Level>
<MessageID>0</MessageID>
<PointValue>2500</PointValue>
<Reproducible>false</Reproducible>
<AllowNonMembers>true</AllowNonMembers>
<Distinct>false</Distinct>
<ProductGroupID>9</ProductGroupID>
<TaskEvent_Points>1</TaskEvent_Points>
<Cumulative>true</Cumulative>
<PreredeemMessageID>0</PreredeemMessageID>
<ValidityFromDate>2023-02-01T00:00:00</ValidityFromDate>
<ValidityToDate>2023-06-07T19:00:00</ValidityToDate>
<isBeyondLevelAllowed>false</isBeyondLevelAllowed>
<VisibilityFromDate>2023-02-01T00:00:00</VisibilityFromDate>
<VisibilityToDate>2023-06-07T19:00:00</VisibilityToDate>
</AchievementTaskInfo>
<AchievementTaskInfo>
<AchievementInfoID>12433</AchievementInfoID>
<AchievementTaskID>2471</AchievementTaskID>
<AchievementTaskGroupID>2418</AchievementTaskGroupID>
<AchievementTaskGroupName>Thawfest 2023 Event Rewards</AchievementTaskGroupName>
<Level>16</Level>
<MessageID>0</MessageID>
<PointValue>3000</PointValue>
<Reproducible>false</Reproducible>
<AllowNonMembers>true</AllowNonMembers>
<Distinct>false</Distinct>
<ProductGroupID>9</ProductGroupID>
<TaskEvent_Points>1</TaskEvent_Points>
<Cumulative>true</Cumulative>
<PreredeemMessageID>0</PreredeemMessageID>
<ValidityFromDate>2023-02-01T00:00:00</ValidityFromDate>
<ValidityToDate>2023-06-07T19:00:00</ValidityToDate>
<isBeyondLevelAllowed>false</isBeyondLevelAllowed>
<VisibilityFromDate>2023-02-01T00:00:00</VisibilityFromDate>
<VisibilityToDate>2023-06-07T19:00:00</VisibilityToDate>
</AchievementTaskInfo>
<AchievementTaskInfo>
<AchievementInfoID>12434</AchievementInfoID>
<AchievementTaskID>2471</AchievementTaskID>
<AchievementTaskGroupID>2418</AchievementTaskGroupID>
<AchievementTaskGroupName>Thawfest 2023 Event Rewards</AchievementTaskGroupName>
<Level>17</Level>
<MessageID>0</MessageID>
<PointValue>3500</PointValue>
<Reproducible>false</Reproducible>
<AllowNonMembers>true</AllowNonMembers>
<Distinct>false</Distinct>
<ProductGroupID>9</ProductGroupID>
<TaskEvent_Points>1</TaskEvent_Points>
<Cumulative>true</Cumulative>
<PreredeemMessageID>0</PreredeemMessageID>
<ValidityFromDate>2023-02-01T00:00:00</ValidityFromDate>
<ValidityToDate>2023-06-07T19:00:00</ValidityToDate>
<isBeyondLevelAllowed>false</isBeyondLevelAllowed>
<VisibilityFromDate>2023-02-01T00:00:00</VisibilityFromDate>
<VisibilityToDate>2023-06-07T19:00:00</VisibilityToDate>
</AchievementTaskInfo>
<AchievementTaskInfo>
<AchievementInfoID>12435</AchievementInfoID>
<AchievementTaskID>2471</AchievementTaskID>
<AchievementTaskGroupID>2418</AchievementTaskGroupID>
<AchievementTaskGroupName>Thawfest 2023 Event Rewards</AchievementTaskGroupName>
<Level>18</Level>
<MessageID>0</MessageID>
<PointValue>4000</PointValue>
<Reproducible>false</Reproducible>
<AllowNonMembers>true</AllowNonMembers>
<Distinct>false</Distinct>
<ProductGroupID>9</ProductGroupID>
<TaskEvent_Points>1</TaskEvent_Points>
<Cumulative>true</Cumulative>
<PreredeemMessageID>0</PreredeemMessageID>
<ValidityFromDate>2023-02-01T00:00:00</ValidityFromDate>
<ValidityToDate>2023-06-07T19:00:00</ValidityToDate>
<isBeyondLevelAllowed>false</isBeyondLevelAllowed>
<VisibilityFromDate>2023-02-01T00:00:00</VisibilityFromDate>
<VisibilityToDate>2023-06-07T19:00:00</VisibilityToDate>
</AchievementTaskInfo>
<AchievementTaskInfo>
<AchievementInfoID>12436</AchievementInfoID>
<AchievementTaskID>2471</AchievementTaskID>
<AchievementTaskGroupID>2418</AchievementTaskGroupID>
<AchievementTaskGroupName>Thawfest 2023 Event Rewards</AchievementTaskGroupName>
<Level>19</Level>
<MessageID>0</MessageID>
<PointValue>4500</PointValue>
<Reproducible>false</Reproducible>
<AllowNonMembers>true</AllowNonMembers>
<Distinct>false</Distinct>
<ProductGroupID>9</ProductGroupID>
<TaskEvent_Points>1</TaskEvent_Points>
<Cumulative>true</Cumulative>
<PreredeemMessageID>0</PreredeemMessageID>
<ValidityFromDate>2023-02-01T00:00:00</ValidityFromDate>
<ValidityToDate>2023-06-07T19:00:00</ValidityToDate>
<isBeyondLevelAllowed>false</isBeyondLevelAllowed>
<VisibilityFromDate>2023-02-01T00:00:00</VisibilityFromDate>
<VisibilityToDate>2023-06-07T19:00:00</VisibilityToDate>
</AchievementTaskInfo>
<AchievementTaskInfo>
<AchievementInfoID>12437</AchievementInfoID>
<AchievementTaskID>2471</AchievementTaskID>
<AchievementTaskGroupID>2418</AchievementTaskGroupID>
<AchievementTaskGroupName>Thawfest 2023 Event Rewards</AchievementTaskGroupName>
<Level>20</Level>
<MessageID>0</MessageID>
<PointValue>5000</PointValue>
<Reproducible>false</Reproducible>
<AllowNonMembers>true</AllowNonMembers>
<Distinct>false</Distinct>
<ProductGroupID>9</ProductGroupID>
<TaskEvent_Points>1</TaskEvent_Points>
<Cumulative>true</Cumulative>
<PreredeemMessageID>0</PreredeemMessageID>
<ValidityFromDate>2023-02-01T00:00:00</ValidityFromDate>
<ValidityToDate>2023-06-07T19:00:00</ValidityToDate>
<isBeyondLevelAllowed>false</isBeyondLevelAllowed>
<VisibilityFromDate>2023-02-01T00:00:00</VisibilityFromDate>
<VisibilityToDate>2023-06-07T19:00:00</VisibilityToDate>
</AchievementTaskInfo>
<AchievementTaskInfo>
<AchievementInfoID>12438</AchievementInfoID>
<AchievementTaskID>2471</AchievementTaskID>
<AchievementTaskGroupID>2418</AchievementTaskGroupID>
<AchievementTaskGroupName>Thawfest 2023 Event Rewards</AchievementTaskGroupName>
<Level>21</Level>
<MessageID>0</MessageID>
<PointValue>5500</PointValue>
<Reproducible>false</Reproducible>
<AllowNonMembers>true</AllowNonMembers>
<Distinct>false</Distinct>
<ProductGroupID>9</ProductGroupID>
<TaskEvent_Points>1</TaskEvent_Points>
<Cumulative>true</Cumulative>
<PreredeemMessageID>0</PreredeemMessageID>
<ValidityFromDate>2023-02-01T00:00:00</ValidityFromDate>
<ValidityToDate>2023-06-07T19:00:00</ValidityToDate>
<isBeyondLevelAllowed>false</isBeyondLevelAllowed>
<VisibilityFromDate>2023-02-01T00:00:00</VisibilityFromDate>
<VisibilityToDate>2023-06-07T19:00:00</VisibilityToDate>
</AchievementTaskInfo>
<AchievementTaskInfo>
<AchievementInfoID>12439</AchievementInfoID>
<AchievementTaskID>2471</AchievementTaskID>
<AchievementTaskGroupID>2418</AchievementTaskGroupID>
<AchievementTaskGroupName>Thawfest 2023 Event Rewards</AchievementTaskGroupName>
<Level>22</Level>
<MessageID>0</MessageID>
<PointValue>6000</PointValue>
<Reproducible>false</Reproducible>
<AllowNonMembers>true</AllowNonMembers>
<Distinct>false</Distinct>
<ProductGroupID>9</ProductGroupID>
<TaskEvent_Points>1</TaskEvent_Points>
<Cumulative>true</Cumulative>
<PreredeemMessageID>0</PreredeemMessageID>
<ValidityFromDate>2023-02-01T00:00:00</ValidityFromDate>
<ValidityToDate>2023-06-07T19:00:00</ValidityToDate>
<isBeyondLevelAllowed>false</isBeyondLevelAllowed>
<VisibilityFromDate>2023-02-01T00:00:00</VisibilityFromDate>
<VisibilityToDate>2023-06-07T19:00:00</VisibilityToDate>
</AchievementTaskInfo>
<AchievementTaskInfo>
<AchievementInfoID>12440</AchievementInfoID>
<AchievementTaskID>2471</AchievementTaskID>
<AchievementTaskGroupID>2418</AchievementTaskGroupID>
<AchievementTaskGroupName>Thawfest 2023 Event Rewards</AchievementTaskGroupName>
<Level>23</Level>
<MessageID>0</MessageID>
<PointValue>6500</PointValue>
<Reproducible>false</Reproducible>
<AllowNonMembers>true</AllowNonMembers>
<Distinct>false</Distinct>
<ProductGroupID>9</ProductGroupID>
<TaskEvent_Points>1</TaskEvent_Points>
<Cumulative>true</Cumulative>
<PreredeemMessageID>0</PreredeemMessageID>
<ValidityFromDate>2023-02-01T00:00:00</ValidityFromDate>
<ValidityToDate>2023-06-07T19:00:00</ValidityToDate>
<isBeyondLevelAllowed>false</isBeyondLevelAllowed>
<VisibilityFromDate>2023-02-01T00:00:00</VisibilityFromDate>
<VisibilityToDate>2023-06-07T19:00:00</VisibilityToDate>
</AchievementTaskInfo>
<AchievementTaskInfo>
<AchievementInfoID>12441</AchievementInfoID>
<AchievementTaskID>2471</AchievementTaskID>
<AchievementTaskGroupID>2418</AchievementTaskGroupID>
<AchievementTaskGroupName>Thawfest 2023 Event Rewards</AchievementTaskGroupName>
<Level>24</Level>
<MessageID>0</MessageID>
<PointValue>7000</PointValue>
<Reproducible>false</Reproducible>
<AllowNonMembers>true</AllowNonMembers>
<Distinct>false</Distinct>
<ProductGroupID>9</ProductGroupID>
<TaskEvent_Points>1</TaskEvent_Points>
<Cumulative>true</Cumulative>
<PreredeemMessageID>0</PreredeemMessageID>
<ValidityFromDate>2023-02-01T00:00:00</ValidityFromDate>
<ValidityToDate>2023-06-07T19:00:00</ValidityToDate>
<isBeyondLevelAllowed>false</isBeyondLevelAllowed>
<VisibilityFromDate>2023-02-01T00:00:00</VisibilityFromDate>
<VisibilityToDate>2023-06-07T19:00:00</VisibilityToDate>
</AchievementTaskInfo>
<AchievementTaskInfo>
<AchievementInfoID>12442</AchievementInfoID>
<AchievementTaskID>2471</AchievementTaskID>
<AchievementTaskGroupID>2418</AchievementTaskGroupID>
<AchievementTaskGroupName>Thawfest 2023 Event Rewards</AchievementTaskGroupName>
<Level>25</Level>
<MessageID>0</MessageID>
<PointValue>7500</PointValue>
<Reproducible>false</Reproducible>
<AllowNonMembers>true</AllowNonMembers>
<Distinct>false</Distinct>
<ProductGroupID>9</ProductGroupID>
<TaskEvent_Points>1</TaskEvent_Points>
<Cumulative>true</Cumulative>
<PreredeemMessageID>0</PreredeemMessageID>
<ValidityFromDate>2023-02-01T00:00:00</ValidityFromDate>
<ValidityToDate>2023-06-07T19:00:00</ValidityToDate>
<isBeyondLevelAllowed>false</isBeyondLevelAllowed>
<VisibilityFromDate>2023-02-01T00:00:00</VisibilityFromDate>
<VisibilityToDate>2023-06-07T19:00:00</VisibilityToDate>
</AchievementTaskInfo>
<AchievementTaskInfo>
<AchievementInfoID>12443</AchievementInfoID>
<AchievementTaskID>2471</AchievementTaskID>
<AchievementTaskGroupID>2418</AchievementTaskGroupID>
<AchievementTaskGroupName>Thawfest 2023 Event Rewards</AchievementTaskGroupName>
<Level>26</Level>
<MessageID>0</MessageID>
<PointValue>8000</PointValue>
<Reproducible>false</Reproducible>
<AllowNonMembers>true</AllowNonMembers>
<Distinct>false</Distinct>
<ProductGroupID>9</ProductGroupID>
<TaskEvent_Points>1</TaskEvent_Points>
<Cumulative>true</Cumulative>
<PreredeemMessageID>0</PreredeemMessageID>
<ValidityFromDate>2023-02-01T00:00:00</ValidityFromDate>
<ValidityToDate>2023-06-07T19:00:00</ValidityToDate>
<isBeyondLevelAllowed>false</isBeyondLevelAllowed>
<VisibilityFromDate>2023-02-01T00:00:00</VisibilityFromDate>
<VisibilityToDate>2023-06-07T19:00:00</VisibilityToDate>
</AchievementTaskInfo>
<AchievementTaskInfo>
<AchievementInfoID>12444</AchievementInfoID>
<AchievementTaskID>2471</AchievementTaskID>
<AchievementTaskGroupID>2418</AchievementTaskGroupID>
<AchievementTaskGroupName>Thawfest 2023 Event Rewards</AchievementTaskGroupName>
<Level>27</Level>
<MessageID>0</MessageID>
<PointValue>8500</PointValue>
<Reproducible>false</Reproducible>
<AllowNonMembers>true</AllowNonMembers>
<Distinct>false</Distinct>
<ProductGroupID>9</ProductGroupID>
<TaskEvent_Points>1</TaskEvent_Points>
<Cumulative>true</Cumulative>
<PreredeemMessageID>0</PreredeemMessageID>
<ValidityFromDate>2023-02-01T00:00:00</ValidityFromDate>
<ValidityToDate>2023-06-07T19:00:00</ValidityToDate>
<isBeyondLevelAllowed>false</isBeyondLevelAllowed>
<VisibilityFromDate>2023-02-01T00:00:00</VisibilityFromDate>
<VisibilityToDate>2023-06-07T19:00:00</VisibilityToDate>
</AchievementTaskInfo>
<AchievementTaskInfo>
<AchievementInfoID>12445</AchievementInfoID>
<AchievementTaskID>2471</AchievementTaskID>
<AchievementTaskGroupID>2418</AchievementTaskGroupID>
<AchievementTaskGroupName>Thawfest 2023 Event Rewards</AchievementTaskGroupName>
<Level>28</Level>
<MessageID>0</MessageID>
<PointValue>9000</PointValue>
<Reproducible>false</Reproducible>
<AllowNonMembers>true</AllowNonMembers>
<Distinct>false</Distinct>
<ProductGroupID>9</ProductGroupID>
<TaskEvent_Points>1</TaskEvent_Points>
<Cumulative>true</Cumulative>
<PreredeemMessageID>0</PreredeemMessageID>
<ValidityFromDate>2023-02-01T00:00:00</ValidityFromDate>
<ValidityToDate>2023-06-07T19:00:00</ValidityToDate>
<isBeyondLevelAllowed>false</isBeyondLevelAllowed>
<VisibilityFromDate>2023-02-01T00:00:00</VisibilityFromDate>
<VisibilityToDate>2023-06-07T19:00:00</VisibilityToDate>
</AchievementTaskInfo>
<AchievementTaskInfo>
<AchievementInfoID>12446</AchievementInfoID>
<AchievementTaskID>2471</AchievementTaskID>
<AchievementTaskGroupID>2418</AchievementTaskGroupID>
<AchievementTaskGroupName>Thawfest 2023 Event Rewards</AchievementTaskGroupName>
<Level>29</Level>
<MessageID>0</MessageID>
<PointValue>9500</PointValue>
<Reproducible>false</Reproducible>
<AllowNonMembers>true</AllowNonMembers>
<Distinct>false</Distinct>
<ProductGroupID>9</ProductGroupID>
<TaskEvent_Points>1</TaskEvent_Points>
<Cumulative>true</Cumulative>
<PreredeemMessageID>0</PreredeemMessageID>
<ValidityFromDate>2023-02-01T00:00:00</ValidityFromDate>
<ValidityToDate>2023-06-07T19:00:00</ValidityToDate>
<isBeyondLevelAllowed>false</isBeyondLevelAllowed>
<VisibilityFromDate>2023-02-01T00:00:00</VisibilityFromDate>
<VisibilityToDate>2023-06-07T19:00:00</VisibilityToDate>
</AchievementTaskInfo>
<AchievementTaskInfo>
<AchievementInfoID>12447</AchievementInfoID>
<AchievementTaskID>2471</AchievementTaskID>
<AchievementTaskGroupID>2418</AchievementTaskGroupID>
<AchievementTaskGroupName>Thawfest 2023 Event Rewards</AchievementTaskGroupName>
<Level>30</Level>
<MessageID>0</MessageID>
<PointValue>10000</PointValue>
<Reproducible>false</Reproducible>
<AllowNonMembers>true</AllowNonMembers>
<Distinct>false</Distinct>
<ProductGroupID>9</ProductGroupID>
<TaskEvent_Points>1</TaskEvent_Points>
<Cumulative>true</Cumulative>
<PreredeemMessageID>0</PreredeemMessageID>
<ValidityFromDate>2023-02-01T00:00:00</ValidityFromDate>
<ValidityToDate>2023-06-07T19:00:00</ValidityToDate>
<isBeyondLevelAllowed>false</isBeyondLevelAllowed>
<VisibilityFromDate>2023-02-01T00:00:00</VisibilityFromDate>
<VisibilityToDate>2023-06-07T19:00:00</VisibilityToDate>
</AchievementTaskInfo>
<AchievementTaskInfo>
<AchievementInfoID>12448</AchievementInfoID>
<AchievementTaskID>2471</AchievementTaskID>
<AchievementTaskGroupID>2418</AchievementTaskGroupID>
<AchievementTaskGroupName>Thawfest 2023 Event Rewards</AchievementTaskGroupName>
<Level>31</Level>
<MessageID>0</MessageID>
<PointValue>11000</PointValue>
<Reproducible>false</Reproducible>
<AllowNonMembers>true</AllowNonMembers>
<Distinct>false</Distinct>
<ProductGroupID>9</ProductGroupID>
<TaskEvent_Points>1</TaskEvent_Points>
<Cumulative>true</Cumulative>
<PreredeemMessageID>0</PreredeemMessageID>
<ValidityFromDate>2023-02-01T00:00:00</ValidityFromDate>
<ValidityToDate>2023-06-07T19:00:00</ValidityToDate>
<isBeyondLevelAllowed>false</isBeyondLevelAllowed>
<VisibilityFromDate>2023-02-01T00:00:00</VisibilityFromDate>
<VisibilityToDate>2023-06-07T19:00:00</VisibilityToDate>
</AchievementTaskInfo>
<AchievementTaskInfo>
<AchievementInfoID>12449</AchievementInfoID>
<AchievementTaskID>2471</AchievementTaskID>
<AchievementTaskGroupID>2418</AchievementTaskGroupID>
<AchievementTaskGroupName>Thawfest 2023 Event Rewards</AchievementTaskGroupName>
<Level>32</Level>
<MessageID>0</MessageID>
<PointValue>12000</PointValue>
<Reproducible>false</Reproducible>
<AllowNonMembers>true</AllowNonMembers>
<Distinct>false</Distinct>
<ProductGroupID>9</ProductGroupID>
<TaskEvent_Points>1</TaskEvent_Points>
<Cumulative>true</Cumulative>
<PreredeemMessageID>0</PreredeemMessageID>
<ValidityFromDate>2023-02-01T00:00:00</ValidityFromDate>
<ValidityToDate>2023-06-07T19:00:00</ValidityToDate>
<isBeyondLevelAllowed>false</isBeyondLevelAllowed>
<VisibilityFromDate>2023-02-01T00:00:00</VisibilityFromDate>
<VisibilityToDate>2023-06-07T19:00:00</VisibilityToDate>
</AchievementTaskInfo>
<AchievementTaskInfo>
<AchievementInfoID>12450</AchievementInfoID>
<AchievementTaskID>2471</AchievementTaskID>
<AchievementTaskGroupID>2418</AchievementTaskGroupID>
<AchievementTaskGroupName>Thawfest 2023 Event Rewards</AchievementTaskGroupName>
<Level>33</Level>
<MessageID>0</MessageID>
<PointValue>13000</PointValue>
<Reproducible>false</Reproducible>
<AllowNonMembers>true</AllowNonMembers>
<Distinct>false</Distinct>
<ProductGroupID>9</ProductGroupID>
<TaskEvent_Points>1</TaskEvent_Points>
<Cumulative>true</Cumulative>
<PreredeemMessageID>0</PreredeemMessageID>
<ValidityFromDate>2023-02-01T00:00:00</ValidityFromDate>
<ValidityToDate>2023-06-07T19:00:00</ValidityToDate>
<isBeyondLevelAllowed>false</isBeyondLevelAllowed>
<VisibilityFromDate>2023-02-01T00:00:00</VisibilityFromDate>
<VisibilityToDate>2023-06-07T19:00:00</VisibilityToDate>
</AchievementTaskInfo>
<AchievementTaskInfo>
<AchievementInfoID>12451</AchievementInfoID>
<AchievementTaskID>2471</AchievementTaskID>
<AchievementTaskGroupID>2418</AchievementTaskGroupID>
<AchievementTaskGroupName>Thawfest 2023 Event Rewards</AchievementTaskGroupName>
<Level>34</Level>
<MessageID>0</MessageID>
<PointValue>14000</PointValue>
<Reproducible>false</Reproducible>
<AllowNonMembers>true</AllowNonMembers>
<Distinct>false</Distinct>
<ProductGroupID>9</ProductGroupID>
<TaskEvent_Points>1</TaskEvent_Points>
<Cumulative>true</Cumulative>
<PreredeemMessageID>0</PreredeemMessageID>
<ValidityFromDate>2023-02-01T00:00:00</ValidityFromDate>
<ValidityToDate>2023-06-07T19:00:00</ValidityToDate>
<isBeyondLevelAllowed>false</isBeyondLevelAllowed>
<VisibilityFromDate>2023-02-01T00:00:00</VisibilityFromDate>
<VisibilityToDate>2023-06-07T19:00:00</VisibilityToDate>
</AchievementTaskInfo>
<AchievementTaskInfo>
<AchievementInfoID>12452</AchievementInfoID>
<AchievementTaskID>2471</AchievementTaskID>
<AchievementTaskGroupID>2418</AchievementTaskGroupID>
<AchievementTaskGroupName>Thawfest 2023 Event Rewards</AchievementTaskGroupName>
<Level>35</Level>
<MessageID>0</MessageID>
<PointValue>15000</PointValue>
<Reproducible>false</Reproducible>
<AllowNonMembers>true</AllowNonMembers>
<Distinct>false</Distinct>
<ProductGroupID>9</ProductGroupID>
<TaskEvent_Points>1</TaskEvent_Points>
<Cumulative>true</Cumulative>
<PreredeemMessageID>0</PreredeemMessageID>
<ValidityFromDate>2023-02-01T00:00:00</ValidityFromDate>
<ValidityToDate>2023-06-07T19:00:00</ValidityToDate>
<isBeyondLevelAllowed>false</isBeyondLevelAllowed>
<VisibilityFromDate>2023-02-01T00:00:00</VisibilityFromDate>
<VisibilityToDate>2023-06-07T19:00:00</VisibilityToDate>
</AchievementTaskInfo>
<AchievementTaskInfo>
<AchievementInfoID>12453</AchievementInfoID>
<AchievementTaskID>2471</AchievementTaskID>
<AchievementTaskGroupID>2418</AchievementTaskGroupID>
<AchievementTaskGroupName>Thawfest 2023 Event Rewards</AchievementTaskGroupName>
<Level>36</Level>
<MessageID>0</MessageID>
<PointValue>16000</PointValue>
<Reproducible>false</Reproducible>
<AllowNonMembers>true</AllowNonMembers>
<Distinct>false</Distinct>
<ProductGroupID>9</ProductGroupID>
<TaskEvent_Points>1</TaskEvent_Points>
<Cumulative>true</Cumulative>
<PreredeemMessageID>0</PreredeemMessageID>
<ValidityFromDate>2023-02-01T00:00:00</ValidityFromDate>
<ValidityToDate>2023-06-07T19:00:00</ValidityToDate>
<isBeyondLevelAllowed>false</isBeyondLevelAllowed>
<VisibilityFromDate>2023-02-01T00:00:00</VisibilityFromDate>
<VisibilityToDate>2023-06-07T19:00:00</VisibilityToDate>
</AchievementTaskInfo>
<AchievementTaskInfo>
<AchievementInfoID>12454</AchievementInfoID>
<AchievementTaskID>2471</AchievementTaskID>
<AchievementTaskGroupID>2418</AchievementTaskGroupID>
<AchievementTaskGroupName>Thawfest 2023 Event Rewards</AchievementTaskGroupName>
<Level>37</Level>
<MessageID>0</MessageID>
<PointValue>17000</PointValue>
<Reproducible>false</Reproducible>
<AllowNonMembers>true</AllowNonMembers>
<Distinct>false</Distinct>
<ProductGroupID>9</ProductGroupID>
<TaskEvent_Points>1</TaskEvent_Points>
<Cumulative>true</Cumulative>
<PreredeemMessageID>0</PreredeemMessageID>
<ValidityFromDate>2023-02-01T00:00:00</ValidityFromDate>
<ValidityToDate>2023-06-07T19:00:00</ValidityToDate>
<isBeyondLevelAllowed>false</isBeyondLevelAllowed>
<VisibilityFromDate>2023-02-01T00:00:00</VisibilityFromDate>
<VisibilityToDate>2023-06-07T19:00:00</VisibilityToDate>
</AchievementTaskInfo>
<AchievementTaskInfo>
<AchievementInfoID>12455</AchievementInfoID>
<AchievementTaskID>2471</AchievementTaskID>
<AchievementTaskGroupID>2418</AchievementTaskGroupID>
<AchievementTaskGroupName>Thawfest 2023 Event Rewards</AchievementTaskGroupName>
<Level>38</Level>
<MessageID>0</MessageID>
<PointValue>18000</PointValue>
<Reproducible>false</Reproducible>
<AllowNonMembers>true</AllowNonMembers>
<Distinct>false</Distinct>
<ProductGroupID>9</ProductGroupID>
<TaskEvent_Points>1</TaskEvent_Points>
<Cumulative>true</Cumulative>
<PreredeemMessageID>0</PreredeemMessageID>
<ValidityFromDate>2023-02-01T00:00:00</ValidityFromDate>
<ValidityToDate>2023-06-07T19:00:00</ValidityToDate>
<isBeyondLevelAllowed>false</isBeyondLevelAllowed>
<VisibilityFromDate>2023-02-01T00:00:00</VisibilityFromDate>
<VisibilityToDate>2023-06-07T19:00:00</VisibilityToDate>
</AchievementTaskInfo>
<AchievementTaskInfo>
<AchievementInfoID>12456</AchievementInfoID>
<AchievementTaskID>2471</AchievementTaskID>
<AchievementTaskGroupID>2418</AchievementTaskGroupID>
<AchievementTaskGroupName>Thawfest 2023 Event Rewards</AchievementTaskGroupName>
<Level>39</Level>
<MessageID>0</MessageID>
<PointValue>19000</PointValue>
<Reproducible>false</Reproducible>
<AllowNonMembers>true</AllowNonMembers>
<Distinct>false</Distinct>
<ProductGroupID>9</ProductGroupID>
<TaskEvent_Points>1</TaskEvent_Points>
<Cumulative>true</Cumulative>
<PreredeemMessageID>0</PreredeemMessageID>
<ValidityFromDate>2023-02-01T00:00:00</ValidityFromDate>
<ValidityToDate>2023-06-07T19:00:00</ValidityToDate>
<isBeyondLevelAllowed>false</isBeyondLevelAllowed>
<VisibilityFromDate>2023-02-01T00:00:00</VisibilityFromDate>
<VisibilityToDate>2023-06-07T19:00:00</VisibilityToDate>
</AchievementTaskInfo>
<AchievementTaskInfo>
<AchievementInfoID>12457</AchievementInfoID>
<AchievementTaskID>2471</AchievementTaskID>
<AchievementTaskGroupID>2418</AchievementTaskGroupID>
<AchievementTaskGroupName>Thawfest 2023 Event Rewards</AchievementTaskGroupName>
<Level>40</Level>
<MessageID>0</MessageID>
<PointValue>20000</PointValue>
<Reproducible>false</Reproducible>
<AllowNonMembers>true</AllowNonMembers>
<Distinct>false</Distinct>
<ProductGroupID>9</ProductGroupID>
<TaskEvent_Points>1</TaskEvent_Points>
<Cumulative>true</Cumulative>
<PreredeemMessageID>0</PreredeemMessageID>
<ValidityFromDate>2023-02-01T00:00:00</ValidityFromDate>
<ValidityToDate>2023-06-07T19:00:00</ValidityToDate>
<isBeyondLevelAllowed>false</isBeyondLevelAllowed>
<VisibilityFromDate>2023-02-01T00:00:00</VisibilityFromDate>
<VisibilityToDate>2023-06-07T19:00:00</VisibilityToDate>
</AchievementTaskInfo>
</ArrayOfAchievementTaskInfo>

File diff suppressed because it is too large Load Diff

View File

@ -39,7 +39,14 @@
<!-- Eat My Dust -->
<VersionMin>0x04000000</VersionMin>
<VersionMax>0x04ffffff</VersionMax>
<ZoneList>BadlandsEMD RoadSideAttractionEMD JunkYardEMD PitRowEMD RacingCircuitEMD MyGarageEMDInt DragonHomeEMD ScorpionHomeEMD</ZoneList>
<ZoneList>BadlandsEMD RoadSideAttractionEMD JunkYardEMD PitRowEMD RacingCircuitEMD MyGarageEMDInt DragonHomeEMD ScorpionHomeEMD CaptureTheFlag CircuitRacing EatMyDust MechanicShopEMDInt</ZoneList>
</Version>
<Version>
<!-- Magic & Mythies -->
<VersionMin>0x80000000</VersionMin>
<VersionMax>0x80ffffff</VersionMax>
<ZoneList>FarmingJSM HubEnchantedJSM HubHollowsJSM HubTreeJSM MythieRaceTrackBroom MythieRaceTrackPet MythieRacingBroom MythieRacingPet StablesJSM TargetPracticeJSM</ZoneList>
</Version>
<!-- Multiple <MMOServerInfo> child can be used instead of <ZoneList>

View File

@ -9,6 +9,9 @@ public enum AchievementPointTypes {
[XmlEnum("2")]
GameCurrency = 2, // gold
[XmlEnum("3")]
Unknown3 = 3, // unknown, used in MB AchievementTasks
[XmlEnum("4")]
Unknown4 = 4,

View File

@ -0,0 +1,32 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "AchievementTaskInfo", Namespace = "")]
[Serializable]
public class AchievementTaskInfo
{
[XmlElement(ElementName = "AchievementInfoID")]
public int InfoID;
[XmlElement(ElementName = "AchievementTaskID")]
public int TaskID;
[XmlElement(ElementName = "PointValue")]
public int PointValue;
[XmlElement(ElementName = "Reproducible")]
public bool Reproducible;
[XmlElement(ElementName = "AchieventTaskReward")]
public AchievementReward[] Rewards;
[XmlElement(ElementName = "AchievementName")]
public string Name;
[XmlElement(ElementName = "AchievementTaskGroupID")]
public int TaskGroupID;
[XmlElement(ElementName = "Level")]
public int Level;
}

View File

@ -0,0 +1,26 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "ATR", Namespace = "")]
[Serializable]
public class AchievementTaskReward
{
[XmlElement(ElementName = "q")]
public int RewardQuantity;
[XmlElement(ElementName = "p")]
public int PointTypeID;
[XmlElement(ElementName = "r")]
public int RewardID;
[XmlElement(ElementName = "pg")]
public int ProductGroupID;
[XmlElement(ElementName = "a")]
public int AchievementInfoID;
[XmlElement(ElementName = "ii", IsNullable = true)]
public int? ItemID;
}

View File

@ -1,14 +0,0 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "AchievementsTaskInfo", Namespace = "")]
[Serializable]
public class AchievementsTaskInfo
{
[XmlElement(ElementName = "TID")]
public int TaskID;
[XmlElement(ElementName = "AR")]
public AchievementReward[] AchievementReward;
}

View File

@ -0,0 +1,11 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "ArrayOfAchievementTaskInfo", Namespace = "http://api.jumpstart.com/")]
[Serializable]
public class ArrayOfAchievementTaskInfo
{
[XmlElement(ElementName = "AchievementTaskInfo")]
public AchievementTaskInfo[] AchievementTaskInfo;
}

View File

@ -0,0 +1,11 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "ArrayOfUserAchievementTask", Namespace = "http://api.jumpstart.com/")]
[Serializable]
public class ArrayOfUserAchievementTask
{
[XmlElement(ElementName = "UserAchievementTask")]
public UserAchievementTask[] UserAchievementTask;
}

View File

@ -0,0 +1,23 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "UAT", Namespace = "")]
[Serializable]
public class UserAchievementTask
{
[XmlElement(ElementName = "gid")]
public int AchievementTaskGroupID;
[XmlElement(ElementName = "aq", IsNullable = true)]
public int? AchievedQuantity; // current points value
[XmlElement(ElementName = "nl", IsNullable = true)]
public int? NextLevel; // next level number
[XmlElement(ElementName = "qr", IsNullable = true)]
public int? QuantityRequired; // points need to reach next level
[XmlElement(ElementName = "ntr", IsNullable = true)]
public AchievementTaskReward[] NextLevelAchievementRewards;
}

View File

@ -82,7 +82,7 @@ namespace sodoff.Services {
viking.AchievementPoints.Add(xpPoints);
}
int initialPoints = xpPoints.Value;
int initialPoints = xpPoints.Value;
xpPoints.Value += value ?? 0;
if (value > 0 && initialPoints > xpPoints.Value) {
@ -154,17 +154,43 @@ namespace sodoff.Services {
}
}
public AchievementReward[] ApplyAchievementRewardsByTask(Viking viking, AchievementTask task) {
var rewards = achievementStore.GetAchievementRewardsByTask(task.TaskID);
if (rewards != null) {
return ApplyAchievementRewards(viking, rewards);
} else {
return new AchievementReward[0];
public AchievementTaskSetResponse ApplyAchievementRewardsByTask(Viking viking, int taskID, uint gameVersion) {
AchievementTaskState? achievementTaskState = viking.AchievementTaskStates.FirstOrDefault(x => x.TaskId == taskID);
int pointValue = (achievementTaskState?.Points ?? 0);
var achievementInfo = achievementStore.GetAchievementTaskInfo(taskID, gameVersion, pointValue);
var lastLevelCompleted = false;
if (achievementInfo == null) return new AchievementTaskSetResponse();
if (pointValue < achievementInfo.PointValue) { // limit points stored value to max points value in achievement tasks
pointValue += 1;
lastLevelCompleted = true;
}
var rewards = (achievementInfo.Reproducible || pointValue == achievementInfo.PointValue)
? ApplyAchievementRewards(viking, achievementInfo.Rewards)
: Array.Empty<AchievementReward>();
if (achievementTaskState == null)
viking.AchievementTaskStates.Add(new AchievementTaskState { TaskId = taskID, Points = pointValue });
else
achievementTaskState.Points = pointValue;
ctx.SaveChanges();
return new AchievementTaskSetResponse {
Success = true,
UserMessage = true, // TODO: placeholder
AchievementName = achievementInfo.Name,
Level = achievementInfo.Level,
AchievementTaskGroupID = achievementInfo.TaskGroupID,
LastLevelCompleted = lastLevelCompleted,
AchievementInfoID = achievementInfo.InfoID,
AchievementRewards = rewards
};
}
public UserGameCurrency GetUserCurrency(Viking viking) {
// TODO: return real values (after implement currency collecting methods)
int? coins = viking.AchievementPoints.FirstOrDefault(x => x.Type == (int)AchievementPointTypes.GameCurrency)?.Value;
int? gems = viking.AchievementPoints.FirstOrDefault(x => x.Type == (int)AchievementPointTypes.CashCurrency)?.Value;
if (coins is null) {
@ -206,6 +232,7 @@ namespace sodoff.Services {
DateRange = new DateRange()
};
}
public ArrayOfUserAchievementInfo GetTopAchievementBuddies(UserAchievementInfoRequest request) {
// TODO: Type and mode are currently ignored
List<UserAchievementInfo> achievementInfo = new();
@ -235,5 +262,47 @@ namespace sodoff.Services {
UserAchievementInfo = achievementInfo.ToArray()
};
}
public UserAchievementTask[] GetUserAchievementTask(Viking viking, uint gameVersion) {
List <UserAchievementTask> userAchievementTasks = new();
foreach (var achievementsGroup in achievementStore.GetAchievementsGroupIdToTaskId(gameVersion)) {
List<AchievementTaskReward> rewards = new();
int nextLevel = 0;
int points = viking.AchievementTaskStates.FirstOrDefault(x => x.TaskId == achievementsGroup.Value)?.Points ?? 0;
var achievementInfo = achievementStore.GetAchievementTaskInfoForNextLevel(
achievementsGroup.Value, gameVersion, points, achievementsGroup.Key
);
if (achievementInfo != null) {
nextLevel = achievementInfo.Level;
if (achievementInfo.Rewards != null) {
foreach (var r in achievementInfo.Rewards) {
rewards.Add(new AchievementTaskReward {
RewardQuantity = r.Amount ?? 0,
PointTypeID = (int)(r.PointTypeID),
ItemID = r.ItemID,
RewardID = r.RewardID,
AchievementInfoID = achievementInfo.InfoID
});
}
}
} else {
achievementInfo = achievementStore.GetAchievementTaskInfoForCurrentLevel(
achievementsGroup.Value, gameVersion, points, achievementsGroup.Key
);
nextLevel = achievementInfo.Level + 1;
}
userAchievementTasks.Add(new UserAchievementTask {
AchievementTaskGroupID = achievementsGroup.Key,
AchievedQuantity = Math.Min(points, achievementInfo.PointValue),
NextLevel = nextLevel,
QuantityRequired = Math.Max(0, achievementInfo.PointValue - points),
NextLevelAchievementRewards = rewards.ToArray()
});
}
return userAchievementTasks.ToArray();
}
}
}

View File

@ -4,33 +4,53 @@ using sodoff.Util;
using System.Reflection;
using System.Xml;
using System.Xml.Linq;
using System.Collections.ObjectModel;
namespace sodoff.Services {
public class AchievementStoreSingleton {
class AchievementTasks {
public Dictionary<int, List<AchievementTaskInfo>> achievementsRewardByTask = new();
public readonly ReadOnlyDictionary<int, int> achievementsGroupIdToTaskId;
public AchievementTasks(string xmlFile) {
AchievementTaskInfo[] allAchievementTaskInfo = XmlUtil.DeserializeXml<AchievementTaskInfo[]>(XmlUtil.ReadResourceXmlString(xmlFile));
Dictionary<int, int> achievementsGroupIdToTaskIdTmp = new();
foreach (var achievementTaskInfo in allAchievementTaskInfo) {
if (!achievementsRewardByTask.ContainsKey(achievementTaskInfo.TaskID)) {
achievementsRewardByTask[achievementTaskInfo.TaskID] = new();
}
achievementsRewardByTask[achievementTaskInfo.TaskID].Add(achievementTaskInfo);
achievementsGroupIdToTaskIdTmp[achievementTaskInfo.TaskGroupID] = achievementTaskInfo.TaskID;
}
achievementsGroupIdToTaskId = new(achievementsGroupIdToTaskIdTmp);
}
}
Dictionary<AchievementPointTypes, UserRank[]> ranks = new();
Dictionary<int, AchievementReward[]> achivmentsRewardByID = new();
Dictionary<int, AchievementReward[]> achivmentsRewardByTask = new();
Dictionary<int, AchievementReward[]> achievementsRewardByID = new();
Dictionary<int, List<AchievementTaskInfo>> achievementsRewardByTask = new();
Dictionary<uint, AchievementTasks> achievementsTasks = new();
int dragonAdultMinXP;
int dragonTitanMinXP;
public AchievementStoreSingleton() {
ArrayOfUserRank allranks = XmlUtil.DeserializeXml<ArrayOfUserRank>(XmlUtil.ReadResourceXmlString("allranks"));
ArrayOfUserRank allranks = XmlUtil.DeserializeXml<ArrayOfUserRank>(XmlUtil.ReadResourceXmlString("ranks.allranks_sod"));
foreach (var pointType in Enum.GetValues<AchievementPointTypes>()) {
ranks[pointType] = allranks.UserRank.Where(r => r.PointTypeID == pointType).ToArray();
}
AchievementsIdInfo[] allAchievementsIdInfo = XmlUtil.DeserializeXml<AchievementsIdInfo[]>(XmlUtil.ReadResourceXmlString("achievementsids"));
AchievementsIdInfo[] allAchievementsIdInfo = XmlUtil.DeserializeXml<AchievementsIdInfo[]>(XmlUtil.ReadResourceXmlString("achievements.achievementid_sod"));
foreach (var achievementsIdInfo in allAchievementsIdInfo) {
achivmentsRewardByID[achievementsIdInfo.AchievementID] = achievementsIdInfo.AchievementReward;
achievementsRewardByID[achievementsIdInfo.AchievementID] = achievementsIdInfo.AchievementReward;
}
AchievementsTaskInfo[] allAchievementsTaskInfo = XmlUtil.DeserializeXml<AchievementsTaskInfo[]>(XmlUtil.ReadResourceXmlString("achievementstasks"));
foreach (var achievementsTaskInfo in allAchievementsTaskInfo) {
achivmentsRewardByTask[achievementsTaskInfo.TaskID] = achievementsTaskInfo.AchievementReward;
}
achievementsTasks[ClientVersion.Min_SoD] = new AchievementTasks("achievements.achievementtaskinfo_sod");
achievementsTasks[ClientVersion.MaM] = new AchievementTasks("achievements.achievementtaskinfo_mam");
achievementsTasks[ClientVersion.MB] = new AchievementTasks("achievements.achievementtaskinfo_mb");
achievementsTasks[ClientVersion.EMD] = new AchievementTasks("achievements.achievementtaskinfo_emd");
achievementsTasks[ClientVersion.SS] = new AchievementTasks("achievements.achievementtaskinfo_ss");
achievementsTasks[ClientVersion.WoJS] = new AchievementTasks("achievements.achievementtaskinfo_wojs");
dragonAdultMinXP = ranks[AchievementPointTypes.DragonXP][10].Value;
dragonTitanMinXP = ranks[AchievementPointTypes.DragonXP][20].Value;
@ -41,19 +61,47 @@ namespace sodoff.Services {
}
public AchievementReward[]? GetAchievementRewardsById(int achievementID) {
if (achivmentsRewardByID.ContainsKey(achievementID)) {
return achivmentsRewardByID[achievementID];
if (achievementsRewardByID.ContainsKey(achievementID)) {
return achievementsRewardByID[achievementID];
} else {
return null;
}
}
public AchievementReward[]? GetAchievementRewardsByTask(int taskID) {
if (achivmentsRewardByTask.ContainsKey(taskID)) {
return achivmentsRewardByTask[taskID];
} else {
return null;
public ReadOnlyDictionary<int, int> GetAchievementsGroupIdToTaskId(uint gameVersion) {
gameVersion = GameVersionForTasks(gameVersion);
if (achievementsTasks.ContainsKey(gameVersion))
return achievementsTasks[gameVersion].achievementsGroupIdToTaskId;
return new ReadOnlyDictionary<int, int>(new Dictionary<int, int>());
}
public List<AchievementTaskInfo>? GetAllAchievementTaskInfo(int taskID, uint gameVersion) {
gameVersion = GameVersionForTasks(gameVersion);
if (achievementsTasks.ContainsKey(gameVersion) && achievementsTasks[gameVersion].achievementsRewardByTask.ContainsKey(taskID)) {
return achievementsTasks[gameVersion].achievementsRewardByTask[taskID];
}
return null;
}
public AchievementTaskInfo? GetAchievementTaskInfo(int taskID, uint gameVersion, int points, int groupID = -1) {
var achievementTasks = GetAchievementTaskInfoForNextLevel(taskID, gameVersion, points, groupID);
if (achievementTasks != null)
return achievementTasks;
return GetAchievementTaskInfoForCurrentLevel(taskID, gameVersion, points, groupID);
}
public AchievementTaskInfo? GetAchievementTaskInfoForNextLevel(int taskID, uint gameVersion, int points, int groupID = -1) {
var achievementTasks = GetAllAchievementTaskInfo(taskID, gameVersion)?.Where(x => x.PointValue > points && (groupID < 0 || x.TaskGroupID == groupID));
if (achievementTasks != null && achievementTasks.Count() > 0)
return achievementTasks.FirstOrDefault(x => x.PointValue == achievementTasks.Min(x => x.PointValue));
return null;
}
public AchievementTaskInfo? GetAchievementTaskInfoForCurrentLevel(int taskID, uint gameVersion, int points, int groupID = -1) {
var achievementTasks = GetAllAchievementTaskInfo(taskID, gameVersion)?.Where(x => x.PointValue <= points && (groupID < 0 || x.TaskGroupID == groupID));
if (achievementTasks != null && achievementTasks.Count() > 0)
return achievementTasks?.FirstOrDefault(x => x.PointValue == achievementTasks.Max(x => x.PointValue));
return null;
}
public int GetUpdatedDragonXP(int dragonXP, int growthState) {
@ -66,5 +114,13 @@ namespace sodoff.Services {
}
return dragonXP;
}
private uint GameVersionForTasks(uint gameVersion) {
// all SoD version of SoD using the same Tasks database
if ((gameVersion & ClientVersion.Min_SoD) == 0xa0000000) return ClientVersion.Min_SoD;
// all version of WoJS (including lands) using the same Tasks database
if (gameVersion <= ClientVersion.Max_OldJS && (gameVersion & ClientVersion.WoJS) != 0) return ClientVersion.WoJS;
return gameVersion;
}
}
}

View File

@ -16,26 +16,30 @@ public class MissionStoreSingleton {
private int[] upcomingMissionsWoJS;
public MissionStoreSingleton() {
ServerMissionArray missionArray = XmlUtil.DeserializeXml<ServerMissionArray>(XmlUtil.ReadResourceXmlString("missions"));
DefaultMissions defaultMissions = XmlUtil.DeserializeXml<DefaultMissions>(XmlUtil.ReadResourceXmlString("defaultmissionlist"));
ServerMissionArray missionArray = XmlUtil.DeserializeXml<ServerMissionArray>(XmlUtil.ReadResourceXmlString("missions.missions_sod"));
DefaultMissions defaultMissions = XmlUtil.DeserializeXml<DefaultMissions>(XmlUtil.ReadResourceXmlString("missions.defaultmissionlist"));
foreach (var mission in missionArray.MissionDataArray) {
SetUpRecursive(mission);
}
activeMissions = defaultMissions.Active;
upcomingMissions = defaultMissions.Upcoming;
defaultMissions = XmlUtil.DeserializeXml<DefaultMissions>(XmlUtil.ReadResourceXmlString("defaultmissionlistv1"));
defaultMissions = XmlUtil.DeserializeXml<DefaultMissions>(XmlUtil.ReadResourceXmlString("missions.defaultmissionlist_sod_v1"));
activeMissionsV1 = defaultMissions.Active;
upcomingMissionsV1 = defaultMissions.Upcoming;
defaultMissions = XmlUtil.DeserializeXml<DefaultMissions>(XmlUtil.ReadResourceXmlString("defaultmissionlistmam"));
missionArray = XmlUtil.DeserializeXml<ServerMissionArray>(XmlUtil.ReadResourceXmlString("missions.missions_mam"));
defaultMissions = XmlUtil.DeserializeXml<DefaultMissions>(XmlUtil.ReadResourceXmlString("missions.defaultmissionlist_mam"));
foreach (var mission in missionArray.MissionDataArray) {
SetUpRecursive(mission);
}
activeMissionsMaM = defaultMissions.Active;
upcomingMissionsMaM = defaultMissions.Upcoming;
missionArray = XmlUtil.DeserializeXml<ServerMissionArray>(XmlUtil.ReadResourceXmlString("missions_wojs"));
defaultMissions = XmlUtil.DeserializeXml<DefaultMissions>(XmlUtil.ReadResourceXmlString("defaultmissionlist_wojs"));
missionArray = XmlUtil.DeserializeXml<ServerMissionArray>(XmlUtil.ReadResourceXmlString("missions.missions_wojs"));
defaultMissions = XmlUtil.DeserializeXml<DefaultMissions>(XmlUtil.ReadResourceXmlString("missions.defaultmissionlist_wojs"));
foreach (var mission in missionArray.MissionDataArray) {
SetUpRecursive(mission); // TODO: use separate missions dict for WoJS (?)
SetUpRecursive(mission);
}
activeMissionsWoJS = defaultMissions.Active;
upcomingMissionsWoJS = defaultMissions.Upcoming;

View File

@ -36,59 +36,6 @@
</When>
</Choose>
<ItemGroup>
<None Remove="Resources\achievementtaskinfo.xml" />
<None Remove="Resources\items.xml" />
<None Remove="Resources\missions.xml" />
<None Remove="Resources\mmo.xml" />
<None Remove="Resources\displaynames.xml" />
<None Remove="Resources\rankattrib.xml" />
<None Remove="Resources\rankattrib_mb.xml" />
<None Remove="Resources\rewardmultiplier.xml" />
<None Remove="Resources\store.xml" />
<None Remove="Resources\allranks.xml" />
<None Remove="Resources\allranks_mb.xml" />
<None Remove="Resources\allranks_wojs.xml" />
<None Remove="Resources\achievementsids.xml" />
<None Remove="Resources\achievementstasks.xml" />
<None Remove="Resources\defaultmissionlist.xml" />
<None Remove="Resources\defaultmissionlistv1.xml" />
<None Remove="Resources\defaultmissionlistmam.xml" />
<None Remove="Resources\defaultmissionlist_wojs.xml" />
<None Remove="Resources\questiondata.xml" />
<None Remove="Resources\content_jukebox.xml" />
<None Remove="Resources\content_movie.xml" />
<None Remove="Resources\content_blastermovie.xml" />
<None Remove="Resources\content_arcade.xml" />
<None Remove="Resources\content_learning.xml" />
<None Remove="Resources\announcements_wojs.xml" />
<None Remove="Resources\announcements_ss.xml" />
<None Remove="Resources\profiletags.xml" />
<None Remove="Resources\defaulthouse.xml" />
</ItemGroup>
<ItemGroup>
<None Update="Resources\childlist.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Resources\store.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Resources\items.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Resources\tutorialmission.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Resources\achievementsids.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Resources\achievementstasks.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Resources\dtrewards.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Resources\mmo.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
@ -99,31 +46,43 @@
<EmbeddedResource Include="Resources\rewardmultiplier.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="Resources\rankattrib.xml">
<EmbeddedResource Include="Resources\ranks\rankattrib.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="Resources\rankattrib_mb.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="Resources\achievementtaskinfo.xml">
<EmbeddedResource Include="Resources\ranks\rankattrib_mb.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="Resources\store.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="Resources\allranks.xml">
<EmbeddedResource Include="Resources\ranks\allranks_sod.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="Resources\allranks_mb.xml">
<EmbeddedResource Include="Resources\ranks\allranks_mb.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="Resources\allranks_wojs.xml">
<EmbeddedResource Include="Resources\ranks\allranks_wojs.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="Resources\achievementsids.xml">
<EmbeddedResource Include="Resources\achievements\achievementid_sod.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="Resources\achievementstasks.xml">
<EmbeddedResource Include="Resources\achievements\achievementtaskinfo_sod.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="Resources\achievements\achievementtaskinfo_mam.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="Resources\achievements\achievementtaskinfo_mb.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="Resources\achievements\achievementtaskinfo_emd.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="Resources\achievements\achievementtaskinfo_ss.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="Resources\achievements\achievementtaskinfo_wojs.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="Resources\dtrewards.xml">
@ -132,22 +91,25 @@
<EmbeddedResource Include="Resources\items.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="Resources\missions.xml">
<EmbeddedResource Include="Resources\missions\missions_sod.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="Resources\missions_wojs.xml">
<EmbeddedResource Include="Resources\missions\missions_mam.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="Resources\defaultmissionlist.xml">
<EmbeddedResource Include="Resources\missions\missions_wojs.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="Resources\defaultmissionlistv1.xml">
<EmbeddedResource Include="Resources\missions\defaultmissionlist.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="Resources\defaultmissionlistmam.xml">
<EmbeddedResource Include="Resources\missions\defaultmissionlist_sod_v1.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="Resources\defaultmissionlist_wojs.xml">
<EmbeddedResource Include="Resources\missions\defaultmissionlist_mam.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="Resources\missions\defaultmissionlist_wojs.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="Resources\questiondata.xml">