mirror of
https://github.com/SoDOff-Project/sodoff.git
synced 2025-10-11 00:08:50 -07:00
support for old ("steps") missions (#20)
* add support for old missions API (aka "steps missions") * config option to disable loading non SoD Data (used only for missions and achievements for now) * make AuthenticateUser endpoint compatible with games that use e-mail as login * add api keys for lands * add GetGameCurrency endpoint * allow create empty stores and add store "8" (empty) --------- Co-authored-by: Robert Paciorek <robert@opcode.eu.org>
This commit is contained in:
parent
13df822608
commit
cecaa50610
@ -44,6 +44,8 @@ By default (modifiable in appsettings.json), files for version 2.5.0 and newer w
|
||||
A sample file is provided for `{PLATFORM} = WIN`, `{VERSION} = 3.31.0`.
|
||||
It assumes that the server address are `localhost:5000` (API) and `localhost:5001` (assets).
|
||||
|
||||
To use this server with games other than School of Dragons you need to change the `LoadNonSoDData` value in `appsettings.json` to `true`.
|
||||
|
||||
#### Asset Server
|
||||
|
||||
Various settings for the asset server are customizable, with the key one being `ProviderURL`, which specifies the source for downloading assets in `partial` mode. By default, it's configured to use archive.org
|
||||
|
@ -6,6 +6,8 @@ public class ApiServerConfig {
|
||||
public int MMOPort { get; set; } = 9933;
|
||||
public uint MMOSupportMinVersion { get; set; } = 0;
|
||||
|
||||
public bool LoadNonSoDData { get; set; } = false;
|
||||
|
||||
public DbProviders DbProvider { get; set; } = DbProviders.SQLite;
|
||||
public string DbPath { get; set; } = string.Empty;
|
||||
public string DbConnection { get; set; } = string.Empty;
|
||||
|
@ -87,12 +87,14 @@ public class AuthenticationController : Controller {
|
||||
[Route("v3/AuthenticationWebService.asmx/AuthenticateUser")]
|
||||
[DecryptRequest("username")]
|
||||
[DecryptRequest("password")]
|
||||
public bool AuthenticateUser() {
|
||||
public bool AuthenticateUser([FromForm] string apiKey) {
|
||||
String username = Request.Form["username"];
|
||||
String password = Request.Form["password"];
|
||||
|
||||
// Authenticate the user
|
||||
User? user = ctx.Users.FirstOrDefault(e => e.Username == username);
|
||||
User? user = (ClientVersion.GetVersion(apiKey) <= ClientVersion.Max_OldJS)
|
||||
? ctx.Users.FirstOrDefault(e => e.Email == username)
|
||||
: ctx.Users.FirstOrDefault(e => e.Username == username);
|
||||
if (user is null || new PasswordHasher<object>().VerifyHashedPassword(null, user.Password, password) != PasswordVerificationResult.Success) {
|
||||
return false;
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ public class ContentController : Controller {
|
||||
private readonly DBContext ctx;
|
||||
private KeyValueService keyValueService;
|
||||
private ItemService itemService;
|
||||
private MissionStoreSingleton missionStore;
|
||||
private MissionService missionService;
|
||||
private RoomService roomService;
|
||||
private AchievementService achievementService;
|
||||
@ -22,6 +23,7 @@ public class ContentController : Controller {
|
||||
private GameDataService gameDataService;
|
||||
private DisplayNamesService displayNamesService;
|
||||
private NeighborhoodService neighborhoodService;
|
||||
private WorldIdService worldIdService;
|
||||
private Random random = new Random();
|
||||
private readonly IOptions<ApiServerConfig> config;
|
||||
|
||||
@ -29,6 +31,7 @@ public class ContentController : Controller {
|
||||
DBContext ctx,
|
||||
KeyValueService keyValueService,
|
||||
ItemService itemService,
|
||||
MissionStoreSingleton missionStore,
|
||||
MissionService missionService,
|
||||
RoomService roomService,
|
||||
AchievementService achievementService,
|
||||
@ -36,11 +39,13 @@ public class ContentController : Controller {
|
||||
GameDataService gameDataService,
|
||||
DisplayNamesService displayNamesService,
|
||||
NeighborhoodService neighborhoodService,
|
||||
WorldIdService worldIdService,
|
||||
IOptions<ApiServerConfig> config
|
||||
) {
|
||||
this.ctx = ctx;
|
||||
this.keyValueService = keyValueService;
|
||||
this.itemService = itemService;
|
||||
this.missionStore = missionStore;
|
||||
this.missionService = missionService;
|
||||
this.roomService = roomService;
|
||||
this.achievementService = achievementService;
|
||||
@ -48,6 +53,7 @@ public class ContentController : Controller {
|
||||
this.gameDataService = gameDataService;
|
||||
this.displayNamesService = displayNamesService;
|
||||
this.neighborhoodService = neighborhoodService;
|
||||
this.worldIdService = worldIdService;
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
@ -1673,10 +1679,17 @@ public class ContentController : Controller {
|
||||
[Route("ContentWebService.asmx/GetUserGameCurrency")]
|
||||
[VikingSession]
|
||||
public IActionResult GetUserGameCurrency(Viking viking) {
|
||||
// TODO: This is a placeholder
|
||||
return Ok(achievementService.GetUserCurrency(viking));
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Produces("application/xml")]
|
||||
[Route("ContentWebService.asmx/GetGameCurrency")]
|
||||
[VikingSession]
|
||||
public IActionResult GetGameCurrency(Viking viking) {
|
||||
return Ok(achievementService.GetUserCurrency(viking).GameCurrency);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Produces("application/xml")]
|
||||
[Route("ContentWebService.asmx/SetGameCurrency")] // used by World Of Jumpstart
|
||||
@ -2121,10 +2134,72 @@ public class ContentController : Controller {
|
||||
|
||||
[HttpPost]
|
||||
[Produces("application/xml")]
|
||||
[Route("MissionWebService.asmx/GetWorldId")] // used by Math Blaster
|
||||
public IActionResult GetWorldId() {
|
||||
// TODO: This is a placeholder
|
||||
return Ok(0);
|
||||
[Route("MissionWebService.asmx/GetWorldId")] // used by Math Blaster and WoJS Adventureland
|
||||
public IActionResult GetWorldId([FromForm] int gameId, [FromForm] string sceneName) {
|
||||
return Ok(worldIdService.GetWorldID(sceneName));
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Produces("application/xml")]
|
||||
[Route("MissionWebService.asmx/GetMission")] // old ("step") missions - used by MB and WoJS lands
|
||||
public IActionResult GetMission([FromForm] int gameId, [FromForm] string name) {
|
||||
return Ok(missionStore.GetStepsMissions(gameId, name));
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Produces("application/xml")]
|
||||
[Route("MissionWebService.asmx/GetStep")] // old ("step") missions - used by MB and WoJS lands
|
||||
public IActionResult GetMissionStep([FromForm] int stepId) {
|
||||
return Ok(missionStore.GetStep(stepId));
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Produces("application/xml")]
|
||||
[Route("ContentWebService.asmx/GetUserMission")] // old ("step") missions - used by MB and WoJS lands
|
||||
[VikingSession]
|
||||
public IActionResult GetUserMission(Viking viking, [FromForm] int worldId) {
|
||||
return Ok(missionService.GetUserMissionData(viking, worldId));
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Produces("application/xml")]
|
||||
[Route("ContentWebService.asmx/SetUserMission")] // old ("step") missions - used by MB and WoJS lands
|
||||
[VikingSession(UseLock=true)]
|
||||
public IActionResult SetUserMission(Viking viking, [FromForm] int worldId, [FromForm] int missionId, [FromForm] int stepId, [FromForm] int taskId) {
|
||||
missionService.SetOrUpdateUserMissionData(viking, worldId, missionId, stepId, taskId);
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Produces("application/xml")]
|
||||
[Route("ContentWebService.asmx/SetUserMissionComplete")] // old ("step") missions - used by MB and WoJS lands
|
||||
[VikingSession]
|
||||
public IActionResult SetUserMissionComplete(Viking viking, [FromForm] int worldId, [FromForm] int missionId) {
|
||||
return Ok(missionService.SetUserMissionCompleted(viking, worldId, missionId, true));
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
//[Produces("application/xml")]
|
||||
[Route("MissionWebService.asmx/GetBadge")] // old ("step") missions - used by MB and WoJS lands
|
||||
public IActionResult GetBadge([FromForm] int gameId) {
|
||||
if (gameId == 1) return Ok(XmlUtil.ReadResourceXmlString("missions.badge_wojs_al"));
|
||||
return Ok();
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Produces("application/xml")]
|
||||
[Route("ContentWebService.asmx/SetUserBadgeComplete")] // old ("step") missions - used by MB and WoJS lands
|
||||
[VikingSession]
|
||||
public IActionResult SetUserBadgeComplete(Viking viking, [FromForm] int badgeId) {
|
||||
return Ok(missionService.SetUserBadgeComplete(viking, badgeId));
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Produces("application/xml")]
|
||||
[Route("ContentWebService.asmx/GetUserBadgeComplete")] // old ("step") missions - used by MB and WoJS lands
|
||||
[VikingSession]
|
||||
public IActionResult GetUserBadgeComplete(Viking viking) {
|
||||
return Ok(missionService.GetUserBadgesCompleted(viking));
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
|
@ -28,6 +28,8 @@ public class DBContext : DbContext {
|
||||
public DbSet<Group> Groups { get; set; } = null!;
|
||||
public DbSet<Rating> Ratings { get; set; } = null!;
|
||||
public DbSet<RatingRank> RatingRanks { get; set; } = null!;
|
||||
public DbSet<UserMissionData> UserMissionData { get; set; } = null!;
|
||||
public DbSet<UserBadgeCompleteData> UserBadgesCompleted { get; set; } = null!;
|
||||
|
||||
private readonly IOptions<ApiServerConfig> config;
|
||||
|
||||
@ -148,6 +150,12 @@ public class DBContext : DbContext {
|
||||
builder.Entity<Viking>().HasMany(v => v.Ratings)
|
||||
.WithOne(r => r.Viking);
|
||||
|
||||
builder.Entity<Viking>().HasMany(v => v.UserMissions)
|
||||
.WithOne(r => r.Viking);
|
||||
|
||||
builder.Entity<Viking>().HasMany(v => v.UserBadgesCompleted)
|
||||
.WithOne(r => r.Viking);
|
||||
|
||||
// Dragons
|
||||
builder.Entity<Dragon>().HasOne(d => d.Viking)
|
||||
.WithMany(e => e.Dragons)
|
||||
@ -284,5 +292,14 @@ public class DBContext : DbContext {
|
||||
|
||||
builder.Entity<RatingRank>().HasMany(rr => rr.Ratings)
|
||||
.WithOne(r => r.Rank);
|
||||
|
||||
// old ("step") missions
|
||||
builder.Entity<UserMissionData>().HasOne(r => r.Viking)
|
||||
.WithMany(v => v.UserMissions)
|
||||
.HasForeignKey(r => r.VikingId);
|
||||
|
||||
builder.Entity<UserBadgeCompleteData>().HasOne(r => r.Viking)
|
||||
.WithMany(v => v.UserBadgesCompleted)
|
||||
.HasForeignKey(r => r.VikingId);
|
||||
}
|
||||
}
|
||||
|
11
src/Model/UserBadgeCompleteData.cs
Normal file
11
src/Model/UserBadgeCompleteData.cs
Normal file
@ -0,0 +1,11 @@
|
||||
namespace sodoff.Model
|
||||
{
|
||||
public class UserBadgeCompleteData
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public int VikingId { get; set; }
|
||||
public int BadgeId { get; set; }
|
||||
|
||||
public virtual Viking? Viking { get; set; }
|
||||
}
|
||||
}
|
18
src/Model/UserMissionData.cs
Normal file
18
src/Model/UserMissionData.cs
Normal file
@ -0,0 +1,18 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace sodoff.Model
|
||||
{
|
||||
[PrimaryKey(nameof(VikingId), nameof(WorldId), nameof(MissionId))]
|
||||
public class UserMissionData
|
||||
{
|
||||
public int VikingId { get; set; }
|
||||
public int WorldId { get; set; }
|
||||
public int MissionId { get; set; }
|
||||
public int StepId { get; set; }
|
||||
public int TaskId { get; set; }
|
||||
public bool IsCompleted { get; set; } = false;
|
||||
|
||||
public virtual Viking? Viking { get; set; }
|
||||
}
|
||||
}
|
@ -42,6 +42,8 @@ public class Viking {
|
||||
public virtual ICollection<Group> Groups { get; set; } = null!;
|
||||
public virtual ICollection<Rating> Ratings { get; set; } = null!;
|
||||
public virtual Dragon? SelectedDragon { get; set; }
|
||||
public virtual ICollection<UserMissionData> UserMissions { get; set; } = null!;
|
||||
public virtual ICollection<UserBadgeCompleteData> UserBadgesCompleted { get; set; } = null!;
|
||||
|
||||
public DateTime? CreationDate { get; set; }
|
||||
public DateTime? BirthDate { get; set; }
|
||||
|
@ -30,6 +30,7 @@ builder.Services.AddSingleton<ItemService>();
|
||||
builder.Services.AddSingleton<StoreService>();
|
||||
builder.Services.AddSingleton<DisplayNamesService>();
|
||||
builder.Services.AddSingleton<MMOConfigService>();
|
||||
builder.Services.AddSingleton<WorldIdService>();
|
||||
|
||||
builder.Services.AddScoped<KeyValueService>();
|
||||
builder.Services.AddScoped<MissionService>();
|
||||
|
23
src/Resources/missions/badge_wojs_al.xml
Normal file
23
src/Resources/missions/badge_wojs_al.xml
Normal file
@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<BadgeData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||
<Badge>
|
||||
<BadgeId>1</BadgeId>
|
||||
<Name>Explorer Badge</Name>
|
||||
<Description>Adventure Land Badge 01</Description>
|
||||
<Experience>1</Experience>
|
||||
<Pieces>10</Pieces>
|
||||
<Mask>Badges01.unity3d/MskBadge10</Mask>
|
||||
<Color>Badges01.unity3d/BadgeK07Color</Color>
|
||||
<Grey>Badges01.unity3d/BadgeK07Grey</Grey>
|
||||
<PieceDialog>
|
||||
<FileName>DlgFrankieB1Piece</FileName>
|
||||
<NPC>NPCs.unity3d/PfFrankie</NPC>
|
||||
<Bundle>RS_DATA/Badges01.unity3d</Bundle>
|
||||
</PieceDialog>
|
||||
<CompleteDialog>
|
||||
<FileName>DlgFrankieB1Complete</FileName>
|
||||
<NPC>NPCs.unity3d/PfFrankie</NPC>
|
||||
<Bundle>RS_DATA/Badges01.unity3d</Bundle>
|
||||
</CompleteDialog>
|
||||
</Badge>
|
||||
</BadgeData>
|
3834
src/Resources/missions/step_missions.xml
Normal file
3834
src/Resources/missions/step_missions.xml
Normal file
File diff suppressed because it is too large
Load Diff
23706
src/Resources/missions/step_missions_steps.xml
Normal file
23706
src/Resources/missions/step_missions_steps.xml
Normal file
File diff suppressed because it is too large
Load Diff
@ -1949,6 +1949,11 @@ SoD 3.31 main store section and subsection filtering:
|
||||
<ii>1597</ii>
|
||||
<ii>1627</ii>
|
||||
</StoreData>
|
||||
<StoreData>
|
||||
<i>8</i>
|
||||
<s>FL Avatar Default</s>
|
||||
<d>The default avatar parts for Adventure Land -- empty</d>
|
||||
</StoreData>
|
||||
<StoreData>
|
||||
<i>9</i>
|
||||
<s>Main Street_Threadz</s>
|
||||
|
152
src/Resources/worlds.xml
Normal file
152
src/Resources/worlds.xml
Normal file
@ -0,0 +1,152 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ArrayOfWorld xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<World>
|
||||
<Scene>TrekAncient01</Scene>
|
||||
<ID>1</ID>
|
||||
</World>
|
||||
<World>
|
||||
<Scene>TrekAncient01Nav</Scene>
|
||||
<ID>1</ID>
|
||||
</World>
|
||||
<World>
|
||||
<Scene>TrekAncient01Roller</Scene>
|
||||
<ID>1</ID>
|
||||
</World>
|
||||
<World>
|
||||
<Scene>Ancient01Zone01</Scene>
|
||||
<ID>1</ID>
|
||||
</World>
|
||||
<World>
|
||||
<Scene>TrekIndustrial01</Scene>
|
||||
<ID>2</ID>
|
||||
</World>
|
||||
<World>
|
||||
<Scene>TrekIndustrial01Nav</Scene>
|
||||
<ID>2</ID>
|
||||
</World>
|
||||
<World>
|
||||
<Scene>TrekIndustrial01Roller</Scene>
|
||||
<ID>2</ID>
|
||||
</World>
|
||||
<World>
|
||||
<Scene>Industrial01Zone01</Scene>
|
||||
<ID>2</ID>
|
||||
</World>
|
||||
<World>
|
||||
<Scene>SeaLab</Scene>
|
||||
<ID>3</ID>
|
||||
</World>
|
||||
<World>
|
||||
<Scene>Aquarium</Scene>
|
||||
<ID>3</ID>
|
||||
</World>
|
||||
<World>
|
||||
<Scene>LrLetItRide</Scene>
|
||||
<ID>3</ID>
|
||||
</World>
|
||||
<World>
|
||||
<Scene>TrainingIsland</Scene>
|
||||
<ID>4</ID>
|
||||
</World>
|
||||
<World>
|
||||
<Scene>HomeBase</Scene>
|
||||
<ID>4</ID>
|
||||
</World>
|
||||
<World>
|
||||
<Scene>TownCenter</Scene>
|
||||
<ID>4</ID>
|
||||
</World>
|
||||
<World>
|
||||
<Scene>MountainJetpack</Scene>
|
||||
<ID>4</ID>
|
||||
</World>
|
||||
<World>
|
||||
<Scene>EnemyValley</Scene>
|
||||
<ID>4</ID>
|
||||
</World>
|
||||
<World>
|
||||
<Scene>DanceScene</Scene>
|
||||
<ID>4</ID>
|
||||
</World>
|
||||
<World>
|
||||
<Scene>ArtHouseAL</Scene>
|
||||
<ID>4</ID>
|
||||
</World>
|
||||
<World>
|
||||
<Scene>AvatarCreatorAL</Scene>
|
||||
<ID>4</ID>
|
||||
</World>
|
||||
<World>
|
||||
<Scene>KnCalendar</Scene>
|
||||
<ID>4</ID>
|
||||
</World>
|
||||
<World>
|
||||
<Scene>Ancient01Zone02</Scene>
|
||||
<ID>5</ID>
|
||||
</World>
|
||||
<World>
|
||||
<Scene>Ancient01Zone03</Scene>
|
||||
<ID>6</ID>
|
||||
</World>
|
||||
<World>
|
||||
<Scene>Ancient01Zone04</Scene>
|
||||
<ID>7</ID>
|
||||
</World>
|
||||
<World>
|
||||
<Scene>Ancient01Zone05</Scene>
|
||||
<ID>8</ID>
|
||||
</World>
|
||||
<World>
|
||||
<Scene>Industrial01Zone02</Scene>
|
||||
<ID>9</ID>
|
||||
</World>
|
||||
<World>
|
||||
<Scene>Industrial01Zone03</Scene>
|
||||
<ID>10</ID>
|
||||
</World>
|
||||
<World>
|
||||
<Scene>Industrial01Zone04</Scene>
|
||||
<ID>11</ID>
|
||||
</World>
|
||||
<World>
|
||||
<Scene>Industrial01Zone05</Scene>
|
||||
<ID>12</ID>
|
||||
</World>
|
||||
<World>
|
||||
<Scene>MerWreck</Scene>
|
||||
<ID>14</ID>
|
||||
</World>
|
||||
<World>
|
||||
<Scene>MerRuins</Scene>
|
||||
<ID>14</ID>
|
||||
</World>
|
||||
<World>
|
||||
<Scene>MerKelp</Scene>
|
||||
<ID>14</ID>
|
||||
</World>
|
||||
<World>
|
||||
<Scene>MerCaverns</Scene>
|
||||
<ID>15</ID>
|
||||
</World>
|
||||
<World>
|
||||
<Scene>MerTown</Scene>
|
||||
<ID>16</ID>
|
||||
</World>
|
||||
<World>
|
||||
<Scene>BubbleTrouble</Scene>
|
||||
<ID>17</ID>
|
||||
</World>
|
||||
<World>
|
||||
<Scene>PearlPush</Scene>
|
||||
<ID>18</ID>
|
||||
</World>
|
||||
<World>
|
||||
<Scene>MB Girls</Scene>
|
||||
<ID>99</ID><!-- sodoff placeholder value -->
|
||||
</World>
|
||||
<World>
|
||||
<Scene>MB Boys</Scene>
|
||||
<ID>99</ID><!-- sodoff placeholder value -->
|
||||
</World>
|
||||
</ArrayOfWorld>
|
||||
|
12
src/Schema/BadgeData.cs
Normal file
12
src/Schema/BadgeData.cs
Normal file
@ -0,0 +1,12 @@
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace sodoff.Schema
|
||||
{
|
||||
[XmlRoot(ElementName = "BadgeData", Namespace = "", IsNullable = true)]
|
||||
[Serializable]
|
||||
public class BadgeData
|
||||
{
|
||||
[XmlElement(ElementName = "Badge")]
|
||||
public BadgeDataBadge[] Badge;
|
||||
}
|
||||
}
|
39
src/Schema/BadgeDataBadge.cs
Normal file
39
src/Schema/BadgeDataBadge.cs
Normal file
@ -0,0 +1,39 @@
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace sodoff.Schema
|
||||
{
|
||||
[XmlRoot(ElementName = "BadgeDataBadge", Namespace = "")]
|
||||
[Serializable]
|
||||
public class BadgeDataBadge
|
||||
{
|
||||
[XmlElement(ElementName = "BadgeId")]
|
||||
public int BadgeId;
|
||||
|
||||
[XmlElement(ElementName = "Name")]
|
||||
public string Name;
|
||||
|
||||
[XmlElement(ElementName = "Description")]
|
||||
public string Description;
|
||||
|
||||
[XmlElement(ElementName = "Experience")]
|
||||
public int Experience;
|
||||
|
||||
[XmlElement(ElementName = "Pieces")]
|
||||
public int Pieces;
|
||||
|
||||
[XmlElement(ElementName = "Mask")]
|
||||
public string Mask;
|
||||
|
||||
[XmlElement(ElementName = "Color")]
|
||||
public string Color;
|
||||
|
||||
[XmlElement(ElementName = "Grey")]
|
||||
public string Grey;
|
||||
|
||||
[XmlElement(ElementName = "PieceDialog", IsNullable = true)]
|
||||
public BadgeDataBadgePieceDialog PieceDialog;
|
||||
|
||||
[XmlElement(ElementName = "CompleteDialog", IsNullable = true)]
|
||||
public BadgeDataBadgeCompleteDialog CompleteDialog;
|
||||
}
|
||||
}
|
18
src/Schema/BadgeDataBadgeCompleteDialog.cs
Normal file
18
src/Schema/BadgeDataBadgeCompleteDialog.cs
Normal file
@ -0,0 +1,18 @@
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace sodoff.Schema
|
||||
{
|
||||
[XmlRoot(ElementName = "BadgeDataBadgeCompleteDialog", Namespace = "")]
|
||||
[Serializable]
|
||||
public class BadgeDataBadgeCompleteDialog
|
||||
{
|
||||
[XmlElement(ElementName = "FileName")]
|
||||
public string FileName;
|
||||
|
||||
[XmlElement(ElementName = "NPC")]
|
||||
public string NPC;
|
||||
|
||||
[XmlElement(ElementName = "Bundle")]
|
||||
public string Bundle;
|
||||
}
|
||||
}
|
18
src/Schema/BadgeDataBadgePieceDialog.cs
Normal file
18
src/Schema/BadgeDataBadgePieceDialog.cs
Normal file
@ -0,0 +1,18 @@
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace sodoff.Schema
|
||||
{
|
||||
[XmlRoot(ElementName = "BadgeDataBadgePieceDialog", Namespace = "")]
|
||||
[Serializable]
|
||||
public class BadgeDataBadgePieceDialog
|
||||
{
|
||||
[XmlElement(ElementName = "FileName")]
|
||||
public string FileName;
|
||||
|
||||
[XmlElement(ElementName = "NPC")]
|
||||
public string NPC;
|
||||
|
||||
[XmlElement(ElementName = "Bundle")]
|
||||
public string Bundle;
|
||||
}
|
||||
}
|
12
src/Schema/MissionData.cs
Normal file
12
src/Schema/MissionData.cs
Normal file
@ -0,0 +1,12 @@
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace sodoff.Schema
|
||||
{
|
||||
[XmlRoot(ElementName = "MissionData", Namespace = "", IsNullable = false)]
|
||||
[Serializable]
|
||||
public class MissionData
|
||||
{
|
||||
[XmlElement(ElementName = "Mission")]
|
||||
public MissionDataMission[] Mission;
|
||||
}
|
||||
}
|
36
src/Schema/MissionDataMission.cs
Normal file
36
src/Schema/MissionDataMission.cs
Normal file
@ -0,0 +1,36 @@
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace sodoff.Schema
|
||||
{
|
||||
[XmlRoot(ElementName = "MissionDataMission", Namespace = "")]
|
||||
[Serializable]
|
||||
public class MissionDataMission
|
||||
{
|
||||
[XmlElement(ElementName = "MissionID")]
|
||||
public int MissionID;
|
||||
|
||||
[XmlElement(ElementName = "Name")]
|
||||
public string Name;
|
||||
|
||||
[XmlElement(ElementName = "DisplayName", IsNullable = true)]
|
||||
public string DisplayName;
|
||||
|
||||
[XmlElement(ElementName = "IconName", IsNullable = true)]
|
||||
public string IconName;
|
||||
|
||||
[XmlElement(ElementName = "Description", IsNullable = true)]
|
||||
public string Description;
|
||||
|
||||
[XmlElement(ElementName = "Experience")]
|
||||
public int Experience;
|
||||
|
||||
[XmlElement(ElementName = "RewardDialog", IsNullable = true)]
|
||||
public MissionDataMissionRewardDialog RewardDialog;
|
||||
|
||||
[XmlElement(ElementName = "UnlockMission")]
|
||||
public int[] UnlockMission;
|
||||
|
||||
[XmlElement(ElementName = "Step", IsNullable = true)]
|
||||
public MissionDataMissionStep[] Step;
|
||||
}
|
||||
}
|
18
src/Schema/MissionDataMissionRewardDialog.cs
Normal file
18
src/Schema/MissionDataMissionRewardDialog.cs
Normal file
@ -0,0 +1,18 @@
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace sodoff.Schema
|
||||
{
|
||||
[XmlRoot(ElementName = "MissionDataMissionRewardDialog", Namespace = "")]
|
||||
[Serializable]
|
||||
public class MissionDataMissionRewardDialog
|
||||
{
|
||||
[XmlElement(ElementName = "FileName")]
|
||||
public string FileName;
|
||||
|
||||
[XmlElement(ElementName = "NPC")]
|
||||
public string NPC;
|
||||
|
||||
[XmlElement(ElementName = "Bundle")]
|
||||
public string Bundle;
|
||||
}
|
||||
}
|
15
src/Schema/MissionDataMissionStep.cs
Normal file
15
src/Schema/MissionDataMissionStep.cs
Normal file
@ -0,0 +1,15 @@
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace sodoff.Schema
|
||||
{
|
||||
[XmlRoot(ElementName = "MissionDataMissionStep", Namespace = "")]
|
||||
[Serializable]
|
||||
public class MissionDataMissionStep
|
||||
{
|
||||
[XmlElement(ElementName = "StepID")]
|
||||
public int StepID;
|
||||
|
||||
[XmlElement(ElementName = "TaskID")]
|
||||
public int[] TaskID;
|
||||
}
|
||||
}
|
36
src/Schema/Step.cs
Normal file
36
src/Schema/Step.cs
Normal file
@ -0,0 +1,36 @@
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace sodoff.Schema
|
||||
{
|
||||
[XmlRoot(ElementName = "Step", Namespace = "", IsNullable = false)]
|
||||
[Serializable]
|
||||
public class Step
|
||||
{
|
||||
[XmlElement(ElementName = "StepID")]
|
||||
public StepStepID StepID;
|
||||
|
||||
[XmlElement(ElementName = "OfferSpeech", IsNullable = true)]
|
||||
public StepOfferSpeech OfferSpeech;
|
||||
|
||||
[XmlElement(ElementName = "EndSpeech", IsNullable = true)]
|
||||
public StepEndSpeech EndSpeech;
|
||||
|
||||
[XmlElement(ElementName = "TasksNeeded")]
|
||||
public int TasksNeeded;
|
||||
|
||||
[XmlElement(ElementName = "Task")]
|
||||
public StepTask[] Task;
|
||||
|
||||
[XmlElement(ElementName = "Message")]
|
||||
public StepMessage[] Message;
|
||||
|
||||
[XmlElement(ElementName = "NPCData")]
|
||||
public StepNPCData[] NPCData;
|
||||
|
||||
[XmlElement(ElementName = "StoreItem")]
|
||||
public StepStoreItem[] StoreItem;
|
||||
|
||||
[XmlElement(ElementName = "StartPlayerItem")]
|
||||
public StepStartPlayerItem[] StartPlayerItem;
|
||||
}
|
||||
}
|
18
src/Schema/StepEndSpeech.cs
Normal file
18
src/Schema/StepEndSpeech.cs
Normal file
@ -0,0 +1,18 @@
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace sodoff.Schema
|
||||
{
|
||||
[XmlRoot(ElementName = "StepEndSpeech", Namespace = "")]
|
||||
[Serializable]
|
||||
public class StepEndSpeech
|
||||
{
|
||||
[XmlElement(ElementName = "FileName")]
|
||||
public string FileName;
|
||||
|
||||
[XmlElement(ElementName = "NPC")]
|
||||
public string NPC;
|
||||
|
||||
[XmlElement(ElementName = "Bundle")]
|
||||
public string Bundle;
|
||||
}
|
||||
}
|
18
src/Schema/StepMessage.cs
Normal file
18
src/Schema/StepMessage.cs
Normal file
@ -0,0 +1,18 @@
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace sodoff.Schema
|
||||
{
|
||||
[XmlRoot(ElementName = "StepMessage", Namespace = "")]
|
||||
[Serializable]
|
||||
public class StepMessage
|
||||
{
|
||||
[XmlElement(ElementName = "Text", IsNullable = true)]
|
||||
public string Text;
|
||||
|
||||
[XmlElement(ElementName = "ItemID", IsNullable = true)]
|
||||
public int? ItemID;
|
||||
|
||||
[XmlElement(ElementName = "Scale", IsNullable = true)]
|
||||
public float? Scale;
|
||||
}
|
||||
}
|
21
src/Schema/StepNPCData.cs
Normal file
21
src/Schema/StepNPCData.cs
Normal file
@ -0,0 +1,21 @@
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace sodoff.Schema
|
||||
{
|
||||
[XmlRoot(ElementName = "StepNPCData", Namespace = "")]
|
||||
[Serializable]
|
||||
public class StepNPCData
|
||||
{
|
||||
[XmlElement(ElementName = "NPC")]
|
||||
public string NPC;
|
||||
|
||||
[XmlElement(ElementName = "Marker")]
|
||||
public string Marker;
|
||||
|
||||
[XmlElement(ElementName = "Scene")]
|
||||
public string Scene;
|
||||
|
||||
[XmlElement(ElementName = "Animation", IsNullable = true)]
|
||||
public string Animation;
|
||||
}
|
||||
}
|
18
src/Schema/StepOfferSpeech.cs
Normal file
18
src/Schema/StepOfferSpeech.cs
Normal file
@ -0,0 +1,18 @@
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace sodoff.Schema
|
||||
{
|
||||
[XmlRoot(ElementName = "StepOfferSpeech", Namespace = "")]
|
||||
[Serializable]
|
||||
public class StepOfferSpeech
|
||||
{
|
||||
[XmlElement(ElementName = "FileName")]
|
||||
public string FileName;
|
||||
|
||||
[XmlElement(ElementName = "NPC")]
|
||||
public string NPC;
|
||||
|
||||
[XmlElement(ElementName = "Bundle")]
|
||||
public string Bundle;
|
||||
}
|
||||
}
|
15
src/Schema/StepStartPlayerItem.cs
Normal file
15
src/Schema/StepStartPlayerItem.cs
Normal file
@ -0,0 +1,15 @@
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace sodoff.Schema
|
||||
{
|
||||
[XmlRoot(ElementName = "StepStartPlayerItem", Namespace = "")]
|
||||
[Serializable]
|
||||
public class StepStartPlayerItem
|
||||
{
|
||||
[XmlElement(ElementName = "ItemID")]
|
||||
public int ItemID;
|
||||
|
||||
[XmlElement(ElementName = "Quantity")]
|
||||
public int Quantity;
|
||||
}
|
||||
}
|
12
src/Schema/StepStepID.cs
Normal file
12
src/Schema/StepStepID.cs
Normal file
@ -0,0 +1,12 @@
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace sodoff.Schema
|
||||
{
|
||||
[XmlRoot(ElementName = "StepStepID", Namespace = "")]
|
||||
[Serializable]
|
||||
public class StepStepID
|
||||
{
|
||||
[XmlText]
|
||||
public int Value;
|
||||
}
|
||||
}
|
15
src/Schema/StepStoreItem.cs
Normal file
15
src/Schema/StepStoreItem.cs
Normal file
@ -0,0 +1,15 @@
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace sodoff.Schema
|
||||
{
|
||||
[XmlRoot(ElementName = "StepStoreItem", Namespace = "")]
|
||||
[Serializable]
|
||||
public class StepStoreItem
|
||||
{
|
||||
[XmlElement(ElementName = "StoreID")]
|
||||
public int StoreID;
|
||||
|
||||
[XmlElement(ElementName = "ItemID")]
|
||||
public int ItemID;
|
||||
}
|
||||
}
|
42
src/Schema/StepTask.cs
Normal file
42
src/Schema/StepTask.cs
Normal file
@ -0,0 +1,42 @@
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace sodoff.Schema
|
||||
{
|
||||
[XmlRoot(ElementName = "StepTask", Namespace = "")]
|
||||
[Serializable]
|
||||
public class StepTask
|
||||
{
|
||||
[XmlElement(ElementName = "TaskID")]
|
||||
public int TaskID;
|
||||
|
||||
[XmlElement(ElementName = "Type")]
|
||||
public string Type;
|
||||
|
||||
[XmlElement(ElementName = "Dialog", IsNullable = true)]
|
||||
public StepTaskDialog Dialog;
|
||||
|
||||
[XmlElement(ElementName = "Message")]
|
||||
public StepTaskMessage[] Message;
|
||||
|
||||
[XmlElement(ElementName = "SetupGroup", IsNullable = true)]
|
||||
public string SetupGroup;
|
||||
|
||||
[XmlElement(ElementName = "SetupScene", IsNullable = true)]
|
||||
public string SetupScene;
|
||||
|
||||
[XmlElement(ElementName = "Help")]
|
||||
public StepTaskHelp[] Help;
|
||||
|
||||
[XmlElement(ElementName = "RewardPlayerItem")]
|
||||
public StepTaskRewardPlayerItem[] RewardPlayerItem;
|
||||
|
||||
[XmlElement(ElementName = "Experience")]
|
||||
public int Experience;
|
||||
|
||||
[XmlElement(ElementName = "Time", IsNullable = true)]
|
||||
public int? Time;
|
||||
|
||||
[XmlElement(ElementName = "Objective")]
|
||||
public StepTaskObjective Objective;
|
||||
}
|
||||
}
|
18
src/Schema/StepTaskDialog.cs
Normal file
18
src/Schema/StepTaskDialog.cs
Normal file
@ -0,0 +1,18 @@
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace sodoff.Schema
|
||||
{
|
||||
[XmlRoot(ElementName = "StepTaskDialog", Namespace = "")]
|
||||
[Serializable]
|
||||
public class StepTaskDialog
|
||||
{
|
||||
[XmlElement(ElementName = "FileName")]
|
||||
public string FileName;
|
||||
|
||||
[XmlElement(ElementName = "NPC")]
|
||||
public string NPC;
|
||||
|
||||
[XmlElement(ElementName = "Bundle")]
|
||||
public string Bundle;
|
||||
}
|
||||
}
|
18
src/Schema/StepTaskHelp.cs
Normal file
18
src/Schema/StepTaskHelp.cs
Normal file
@ -0,0 +1,18 @@
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace sodoff.Schema
|
||||
{
|
||||
[XmlRoot(ElementName = "StepTaskHelp", Namespace = "")]
|
||||
[Serializable]
|
||||
public class StepTaskHelp
|
||||
{
|
||||
[XmlElement(ElementName = "FileName")]
|
||||
public string FileName;
|
||||
|
||||
[XmlElement(ElementName = "NPC")]
|
||||
public string NPC;
|
||||
|
||||
[XmlElement(ElementName = "Bundle")]
|
||||
public string Bundle;
|
||||
}
|
||||
}
|
18
src/Schema/StepTaskMessage.cs
Normal file
18
src/Schema/StepTaskMessage.cs
Normal file
@ -0,0 +1,18 @@
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace sodoff.Schema
|
||||
{
|
||||
[XmlRoot(ElementName = "StepTaskMessage", Namespace = "")]
|
||||
[Serializable]
|
||||
public class StepTaskMessage
|
||||
{
|
||||
[XmlElement(ElementName = "Text", IsNullable = true)]
|
||||
public string Text;
|
||||
|
||||
[XmlElement(ElementName = "ItemID", IsNullable = true)]
|
||||
public int? ItemID;
|
||||
|
||||
[XmlElement(ElementName = "Scale", IsNullable = true)]
|
||||
public float? Scale;
|
||||
}
|
||||
}
|
57
src/Schema/StepTaskObjective.cs
Normal file
57
src/Schema/StepTaskObjective.cs
Normal file
@ -0,0 +1,57 @@
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace sodoff.Schema
|
||||
{
|
||||
[XmlRoot(ElementName = "StepTaskObjective", Namespace = "")]
|
||||
[Serializable]
|
||||
public class StepTaskObjective
|
||||
{
|
||||
[XmlElement(ElementName = "Beacon", IsNullable = true)]
|
||||
public bool? Beacon;
|
||||
|
||||
[XmlElement(ElementName = "NPC", IsNullable = true)]
|
||||
public string NPC;
|
||||
|
||||
[XmlElement(ElementName = "Marker", IsNullable = true)]
|
||||
public string Marker;
|
||||
|
||||
[XmlElement(ElementName = "Scene", IsNullable = true)]
|
||||
public string Scene;
|
||||
|
||||
[XmlElement(ElementName = "Range", IsNullable = true)]
|
||||
public float? Range;
|
||||
|
||||
[XmlElement(ElementName = "Module", IsNullable = true)]
|
||||
public string Module;
|
||||
|
||||
[XmlElement(ElementName = "Group", IsNullable = true)]
|
||||
public string Group;
|
||||
|
||||
[XmlElement(ElementName = "Object", IsNullable = true)]
|
||||
public string Object;
|
||||
|
||||
[XmlElement(ElementName = "StoreID", IsNullable = true)]
|
||||
public int? StoreID;
|
||||
|
||||
[XmlElement(ElementName = "ItemID", IsNullable = true)]
|
||||
public int? ItemID;
|
||||
|
||||
[XmlElement(ElementName = "ItemName", IsNullable = true)]
|
||||
public string ItemName;
|
||||
|
||||
[XmlElement(ElementName = "CategoryID", IsNullable = true)]
|
||||
public int? CategoryID;
|
||||
|
||||
[XmlElement(ElementName = "AttributeID")]
|
||||
public int[] AttributeID;
|
||||
|
||||
[XmlElement(ElementName = "Quantity", IsNullable = true)]
|
||||
public int? Quantity;
|
||||
|
||||
[XmlElement(ElementName = "Photo", IsNullable = true)]
|
||||
public StepTaskObjectivePhoto Photo;
|
||||
|
||||
[XmlElement(ElementName = "Creative", IsNullable = true)]
|
||||
public StepTaskObjectiveCreative Creative;
|
||||
}
|
||||
}
|
15
src/Schema/StepTaskObjectiveCreative.cs
Normal file
15
src/Schema/StepTaskObjectiveCreative.cs
Normal file
@ -0,0 +1,15 @@
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace sodoff.Schema
|
||||
{
|
||||
[XmlRoot(ElementName = "StepTaskObjectiveCreative", Namespace = "")]
|
||||
[Serializable]
|
||||
public class StepTaskObjectiveCreative
|
||||
{
|
||||
[XmlElement(ElementName = "Type")]
|
||||
public int Type;
|
||||
|
||||
[XmlElement(ElementName = "AttributeID")]
|
||||
public int[] AttributeID;
|
||||
}
|
||||
}
|
24
src/Schema/StepTaskObjectivePhoto.cs
Normal file
24
src/Schema/StepTaskObjectivePhoto.cs
Normal file
@ -0,0 +1,24 @@
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace sodoff.Schema
|
||||
{
|
||||
[XmlRoot(ElementName = "StepTaskObjectivePhoto", Namespace = "")]
|
||||
[Serializable]
|
||||
public class StepTaskObjectivePhoto
|
||||
{
|
||||
[XmlElement(ElementName = "ItemName")]
|
||||
public string[] ItemName;
|
||||
|
||||
[XmlElement(ElementName = "NPC")]
|
||||
public string[] NPC;
|
||||
|
||||
[XmlElement(ElementName = "CategoryID")]
|
||||
public int[] CategoryID;
|
||||
|
||||
[XmlElement(ElementName = "AttributeID")]
|
||||
public int[] AttributeID;
|
||||
|
||||
[XmlElement(ElementName = "Quantity")]
|
||||
public int Quantity;
|
||||
}
|
||||
}
|
15
src/Schema/StepTaskRewardPlayerItem.cs
Normal file
15
src/Schema/StepTaskRewardPlayerItem.cs
Normal file
@ -0,0 +1,15 @@
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace sodoff.Schema
|
||||
{
|
||||
[XmlRoot(ElementName = "StepTaskRewardPlayerItem", Namespace = "")]
|
||||
[Serializable]
|
||||
public class StepTaskRewardPlayerItem
|
||||
{
|
||||
[XmlElement(ElementName = "ItemID")]
|
||||
public int ItemID;
|
||||
|
||||
[XmlElement(ElementName = "Quantity")]
|
||||
public int Quantity;
|
||||
}
|
||||
}
|
16
src/Schema/StepsMissionsGroup.cs
Normal file
16
src/Schema/StepsMissionsGroup.cs
Normal file
@ -0,0 +1,16 @@
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace sodoff.Schema;
|
||||
|
||||
[XmlRoot(ElementName = "StepsMissionsGroup", Namespace = "")]
|
||||
[Serializable]
|
||||
public class StepsMissionsGroup {
|
||||
[XmlElement(ElementName = "GameId")]
|
||||
public int GameId;
|
||||
|
||||
[XmlElement(ElementName = "WorldName")]
|
||||
public string WorldName;
|
||||
|
||||
[XmlElement(ElementName = "MissionData")]
|
||||
public MissionData MissionData;
|
||||
}
|
12
src/Schema/UserBadge.cs
Normal file
12
src/Schema/UserBadge.cs
Normal file
@ -0,0 +1,12 @@
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace sodoff.Schema
|
||||
{
|
||||
[XmlRoot(ElementName = "UserBadge", Namespace = "", IsNullable = false)]
|
||||
[Serializable]
|
||||
public class UserBadge
|
||||
{
|
||||
[XmlElement(ElementName = "BadgeId")]
|
||||
public int[] BadgeId;
|
||||
}
|
||||
}
|
15
src/Schema/UserMissionData.cs
Normal file
15
src/Schema/UserMissionData.cs
Normal file
@ -0,0 +1,15 @@
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace sodoff.Schema
|
||||
{
|
||||
[XmlRoot(ElementName = "UserMissionData", Namespace = "")]
|
||||
[Serializable]
|
||||
public class UserMissionData
|
||||
{
|
||||
[XmlElement(ElementName = "Mission")]
|
||||
public UserMissionDataMission[] Mission;
|
||||
|
||||
[XmlElement(ElementName = "MissionComplete")]
|
||||
public int[] MissionComplete;
|
||||
}
|
||||
}
|
15
src/Schema/UserMissionDataMission.cs
Normal file
15
src/Schema/UserMissionDataMission.cs
Normal file
@ -0,0 +1,15 @@
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace sodoff.Schema
|
||||
{
|
||||
[XmlRoot(ElementName = "UserMissionDataMission", Namespace = "")]
|
||||
[Serializable]
|
||||
public class UserMissionDataMission
|
||||
{
|
||||
[XmlElement(ElementName = "MissionId")]
|
||||
public int MissionId;
|
||||
|
||||
[XmlElement(ElementName = "Step")]
|
||||
public UserMissionDataMissionStep[] Step;
|
||||
}
|
||||
}
|
15
src/Schema/UserMissionDataMissionStep.cs
Normal file
15
src/Schema/UserMissionDataMissionStep.cs
Normal file
@ -0,0 +1,15 @@
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace sodoff.Schema
|
||||
{
|
||||
[XmlRoot(ElementName = "UserMissionDataMissionStep", Namespace = "")]
|
||||
[Serializable]
|
||||
public class UserMissionDataMissionStep
|
||||
{
|
||||
[XmlElement(ElementName = "StepId")]
|
||||
public int StepId;
|
||||
|
||||
[XmlElement(ElementName = "TaskId")]
|
||||
public int[] TaskId;
|
||||
}
|
||||
}
|
12
src/Schema/World.cs
Normal file
12
src/Schema/World.cs
Normal file
@ -0,0 +1,12 @@
|
||||
using System.Xml.Serialization;
|
||||
|
||||
[XmlRoot(ElementName = "World", Namespace = "")]
|
||||
[Serializable]
|
||||
public class World
|
||||
{
|
||||
[XmlElement(ElementName = "Scene")]
|
||||
public string Scene;
|
||||
|
||||
[XmlElement(ElementName = "ID")]
|
||||
public int ID;
|
||||
}
|
@ -1,10 +1,12 @@
|
||||
using sodoff.Schema;
|
||||
using sodoff.Model;
|
||||
using sodoff.Util;
|
||||
using sodoff.Configuration;
|
||||
using System.Reflection;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
using System.Collections.ObjectModel;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace sodoff.Services {
|
||||
public class AchievementStoreSingleton {
|
||||
@ -34,7 +36,7 @@ namespace sodoff.Services {
|
||||
int dragonAdultMinXP;
|
||||
int dragonTitanMinXP;
|
||||
|
||||
public AchievementStoreSingleton() {
|
||||
public AchievementStoreSingleton(IOptions<ApiServerConfig> config) {
|
||||
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();
|
||||
@ -46,11 +48,13 @@ namespace sodoff.Services {
|
||||
}
|
||||
|
||||
achievementsTasks[ClientVersion.Min_SoD] = new AchievementTasks("achievements.achievementtaskinfo_sod");
|
||||
if (config.Value.LoadNonSoDData) {
|
||||
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;
|
||||
|
@ -54,6 +54,109 @@ public class MissionService {
|
||||
return mission;
|
||||
}
|
||||
|
||||
public Schema.UserMissionData GetUserMissionData(Viking viking, int worldId) {
|
||||
Schema.UserMissionData umdRes = new();
|
||||
|
||||
// instantiate schema lists and int lists
|
||||
List<int> userMissionsCompletedIds = new();
|
||||
List<UserMissionDataMission> missions = new();
|
||||
|
||||
// get all initiated missions
|
||||
List<Model.UserMissionData> vikingUmds = viking.UserMissions.Where(e => e.WorldId == worldId).ToList();
|
||||
|
||||
foreach (Model.UserMissionData mission in vikingUmds) {
|
||||
missions.Add(new UserMissionDataMission {
|
||||
MissionId = mission.MissionId,
|
||||
Step = new UserMissionDataMissionStep[] { new UserMissionDataMissionStep {
|
||||
// NOTE: we store in database only last StepId and TaskId – this is different behavior than og
|
||||
StepId = mission.StepId,
|
||||
TaskId = new int[] {mission.TaskId}
|
||||
}}
|
||||
});
|
||||
}
|
||||
|
||||
// add completed mission id's to usermissionscompletedids
|
||||
List<Model.UserMissionData> vikingCompletedUmds = vikingUmds.Where(e => e.IsCompleted == true).ToList();
|
||||
|
||||
foreach (Model.UserMissionData mission in vikingCompletedUmds)
|
||||
{
|
||||
userMissionsCompletedIds.Add(mission.MissionId);
|
||||
}
|
||||
|
||||
// construct response
|
||||
umdRes.Mission = missions.ToArray();
|
||||
umdRes.MissionComplete = userMissionsCompletedIds.ToArray();
|
||||
|
||||
// return
|
||||
return umdRes;
|
||||
}
|
||||
|
||||
public UserBadge GetUserBadgesCompleted(Viking viking)
|
||||
{
|
||||
// get badges
|
||||
List<UserBadgeCompleteData> userBadgesCompleted = viking.UserBadgesCompleted.ToList();
|
||||
List<int> completedBadgeIds = new List<int>();
|
||||
|
||||
foreach (var userBadge in userBadgesCompleted)
|
||||
{
|
||||
completedBadgeIds.Add(userBadge.BadgeId);
|
||||
}
|
||||
|
||||
return new UserBadge { BadgeId = completedBadgeIds.ToArray() };
|
||||
}
|
||||
|
||||
public void SetOrUpdateUserMissionData(Viking viking, int worldId, int missionId, int stepId, int taskId) {
|
||||
// find any existing records of this mission
|
||||
Model.UserMissionData? missionData = viking.UserMissions.Where(e => e.WorldId == worldId)
|
||||
.Where(e => e.MissionId == missionId)
|
||||
.FirstOrDefault();
|
||||
|
||||
if (missionData != null) {
|
||||
missionData.StepId = stepId;
|
||||
missionData.TaskId = taskId;
|
||||
} else {
|
||||
viking.UserMissions.Add(new Model.UserMissionData() {
|
||||
WorldId = worldId,
|
||||
MissionId = missionId,
|
||||
StepId = stepId,
|
||||
TaskId = taskId
|
||||
});
|
||||
}
|
||||
ctx.SaveChanges();
|
||||
}
|
||||
|
||||
public bool SetUserMissionCompleted(Viking viking, int worldId, int missionId, bool isCompleted)
|
||||
{
|
||||
Model.UserMissionData? mission = viking.UserMissions.Where(e => e.WorldId == worldId)
|
||||
.Where(e => e.MissionId == missionId)
|
||||
.FirstOrDefault();
|
||||
|
||||
if (mission != null)
|
||||
{
|
||||
// set mission complete
|
||||
mission.IsCompleted = isCompleted;
|
||||
|
||||
// add jumpstars for completing the mission
|
||||
if (isCompleted) achievementService.AddAchievementPoints(viking, AchievementPointTypes.PlayerXP, 25); // hardcoding earning 25 for now
|
||||
|
||||
ctx.SaveChanges();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool SetUserBadgeComplete(Viking viking, int gameId)
|
||||
{
|
||||
// add completed badge to database
|
||||
UserBadgeCompleteData userBadgeCompleteData = new() { BadgeId = gameId };
|
||||
|
||||
viking.UserBadgesCompleted.Add(userBadgeCompleteData);
|
||||
ctx.SaveChanges();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public List<MissionCompletedResult> UpdateTaskProgress(int missionId, int taskId, int userId, bool completed, string xmlPayload, uint gameVersion) {
|
||||
SetTaskProgressDB(missionId, taskId, userId, completed, xmlPayload);
|
||||
|
||||
|
@ -1,11 +1,15 @@
|
||||
using sodoff.Schema;
|
||||
using sodoff.Util;
|
||||
using sodoff.Configuration;
|
||||
using Microsoft.Extensions.Options;
|
||||
using System.Runtime.Serialization.Formatters.Binary;
|
||||
|
||||
namespace sodoff.Services;
|
||||
public class MissionStoreSingleton {
|
||||
|
||||
private Dictionary<int, Mission> missions = new();
|
||||
private Dictionary<(int, string), MissionData> stepsMissions = new();
|
||||
private Dictionary<int, Step> steps = new();
|
||||
private int[] activeMissions;
|
||||
private int[] upcomingMissions;
|
||||
private int[] activeMissionsV1;
|
||||
@ -15,7 +19,7 @@ public class MissionStoreSingleton {
|
||||
private int[] activeMissionsWoJS;
|
||||
private int[] upcomingMissionsWoJS;
|
||||
|
||||
public MissionStoreSingleton() {
|
||||
public MissionStoreSingleton(IOptions<ApiServerConfig> config) {
|
||||
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) {
|
||||
@ -28,6 +32,7 @@ public class MissionStoreSingleton {
|
||||
activeMissionsV1 = defaultMissions.Active;
|
||||
upcomingMissionsV1 = defaultMissions.Upcoming;
|
||||
|
||||
if (config.Value.LoadNonSoDData) {
|
||||
missionArray = XmlUtil.DeserializeXml<ServerMissionArray>(XmlUtil.ReadResourceXmlString("missions.missions_mam"));
|
||||
defaultMissions = XmlUtil.DeserializeXml<DefaultMissions>(XmlUtil.ReadResourceXmlString("missions.defaultmissionlist_mam"));
|
||||
foreach (var mission in missionArray.MissionDataArray) {
|
||||
@ -43,6 +48,17 @@ public class MissionStoreSingleton {
|
||||
}
|
||||
activeMissionsWoJS = defaultMissions.Active;
|
||||
upcomingMissionsWoJS = defaultMissions.Upcoming;
|
||||
|
||||
var stepsMissionsArray = XmlUtil.DeserializeXml<StepsMissionsGroup[]>(XmlUtil.ReadResourceXmlString("missions.step_missions"));
|
||||
foreach (var missionGroup in stepsMissionsArray) {
|
||||
stepsMissions.Add((missionGroup.GameId, missionGroup.WorldName), missionGroup.MissionData);
|
||||
}
|
||||
|
||||
var stepArray = XmlUtil.DeserializeXml<Step[]>(XmlUtil.ReadResourceXmlString("missions.step_missions_steps"));
|
||||
foreach (var step in stepArray) {
|
||||
steps.Add(step.StepID.Value, step);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Mission GetMission(int missionID) {
|
||||
@ -81,6 +97,21 @@ public class MissionStoreSingleton {
|
||||
return new int[0];
|
||||
}
|
||||
|
||||
public MissionData GetStepsMissions(int gameId, string worldName) {
|
||||
if (stepsMissions.ContainsKey((gameId, worldName))) {
|
||||
return stepsMissions[(gameId, worldName)];
|
||||
} else if (stepsMissions.ContainsKey((gameId, "_default_"))) {
|
||||
return stepsMissions[(gameId, "_default_")];
|
||||
} else {
|
||||
Console.WriteLine($"Can't find missions for gameId={gameId} worldName={worldName}");
|
||||
return new MissionData();
|
||||
}
|
||||
}
|
||||
|
||||
public Step GetStep(int stepID) {
|
||||
return steps[stepID];
|
||||
}
|
||||
|
||||
private void SetUpRecursive(Mission mission) {
|
||||
missions.Add(mission.MissionID, mission);
|
||||
foreach (var innerMission in mission.Missions) {
|
||||
|
@ -19,12 +19,14 @@ public class StoreService {
|
||||
List<ItemData> itemsList = new();
|
||||
IEnumerable<ItemsInStoreDataSale>? memberSales = s.SalesAtStore?.Where(x => x.ForMembers == true);
|
||||
IEnumerable<ItemsInStoreDataSale>? normalSales = s.SalesAtStore?.Where(x => x.ForMembers == false || x.ForMembers == null);
|
||||
if (s.ItemId != null) {
|
||||
for (int i = 0; i < s.ItemId.Length; ++i) {
|
||||
ItemData item = itemService.GetItem(s.ItemId[i]);
|
||||
if (item is null) continue; // skip removed items
|
||||
itemsList.Add(item);
|
||||
UpdateItemSaleModifier(item, memberSales, normalSales);
|
||||
}
|
||||
}
|
||||
foreach (int itemID in moddingService.GetStoreItem(s.Id)) {
|
||||
ItemData item = itemService.GetItem(itemID);
|
||||
itemsList.Add(item);
|
||||
|
25
src/Services/WorldIdService.cs
Normal file
25
src/Services/WorldIdService.cs
Normal file
@ -0,0 +1,25 @@
|
||||
using sodoff.Schema;
|
||||
using sodoff.Util;
|
||||
|
||||
namespace sodoff.Services;
|
||||
|
||||
public class WorldIdService {
|
||||
Dictionary<string, int> worlds_id = new();
|
||||
|
||||
public WorldIdService()
|
||||
{
|
||||
var worlds = XmlUtil.DeserializeXml<World[]>(XmlUtil.ReadResourceXmlString("worlds"));
|
||||
foreach (var w in worlds)
|
||||
{
|
||||
worlds_id[w.Scene] = w.ID;
|
||||
}
|
||||
}
|
||||
|
||||
public int GetWorldID(string mapName)
|
||||
{
|
||||
if (worlds_id.ContainsKey(mapName))
|
||||
return worlds_id[mapName];
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
}
|
@ -8,6 +8,9 @@ public class ClientVersion {
|
||||
public const uint SS = 0x02000000;
|
||||
public const uint WoJS = 0x01000000;
|
||||
public const uint WoJS_AdvLand = 0x01000100; // World of JumpStart -- Adventureland
|
||||
public const uint WoJS_FutureLand = 0x01000200; // World of JumpStart -- Futureland
|
||||
public const uint WoJS_MarineLand = 0x01000300; // World of JumpStart -- Marineland
|
||||
public const uint WoJS_StoryLand = 0x01000400; // World of JumpStart -- Storyland
|
||||
public const uint WoJS_NewAvatar = 0x01010000; // World of JumpStart with new avatars (e.g. 1.21)
|
||||
|
||||
public static uint GetVersion(string apiKey) {
|
||||
@ -49,6 +52,18 @@ public class ClientVersion {
|
||||
apiKey == "b4e0f71a-1cda-462a-97b3-0b355e87e0c8"
|
||||
) {
|
||||
return WoJS_AdvLand;
|
||||
} else if (
|
||||
apiKey == "4fb5e29f-64e7-4cbb-8554-6f6c54b57597"
|
||||
) {
|
||||
return WoJS_FutureLand;
|
||||
} else if (
|
||||
apiKey == "dc37ef0d-e1f8-4718-8239-73e68424e384"
|
||||
) {
|
||||
return WoJS_MarineLand;
|
||||
} else if (
|
||||
apiKey == "bd69b6b9-a921-4741-a2a0-92fc40cc2e58"
|
||||
) {
|
||||
return WoJS_StoryLand;
|
||||
}
|
||||
Console.WriteLine($"Unknown apiKey value: {apiKey}");
|
||||
return 0;
|
||||
|
@ -57,6 +57,9 @@
|
||||
"// MMOSupportMinVersion": "Minimum client version allowed to use MMO. For example: '0xa3a31a0a' mean SoD 3.31, '0xa0000000' mean all SoD version, 0 mean all games.",
|
||||
"MMOSupportMinVersion": "0",
|
||||
|
||||
"// LoadNonSoDData": "set to 'true' to support non SoD games, set to 'false' to reduce memory usage",
|
||||
"LoadNonSoDData": true,
|
||||
|
||||
"// DbProvider": "Select database backend to use: SQLite, PostgreSQL, MySQL (availability may depend on build options)",
|
||||
"DbProvider": "SQLite",
|
||||
|
||||
|
@ -142,5 +142,17 @@
|
||||
<EmbeddedResource Include="Resources\defaulthouse.xml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Resources\worlds.xml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Resources\missions\step_missions_steps.xml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Resources\missions\step_missions.xml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Resources\missions\badge_wojs_al.xml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
Loading…
x
Reference in New Issue
Block a user