Merge pull request #2 from hictooth/hictooth/create-profile

create profile
This commit is contained in:
Spirtix 2023-06-19 21:32:25 +02:00 committed by GitHub
commit dcbeec590a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
59 changed files with 74119 additions and 48 deletions

View File

@ -3,7 +3,8 @@ import mitmproxy.http
def routable(path): def routable(path):
methods = ['GetRules', 'LoginParent', 'RegisterParent', 'GetSubscriptionInfo', 'GetUserInfoByApiToken', 'IsValidApiToken_V2', 'ValidateName', 'GetDefaultNameSuggestion', 'RegisterChild', 'GetProfileByUserId', 'LoginChild', 'GetUserProfileByUserID', 'GetKeyValuePair', 'SetKeyValuePair', 'GetKeyValuePairByUserID', 'SetKeyValuePairByUserID'] methods = ['GetRules', 'LoginParent', 'RegisterParent', 'GetSubscriptionInfo', 'GetUserInfoByApiToken', 'IsValidApiToken_V2', 'ValidateName', 'GetDefaultNameSuggestion', 'RegisterChild', 'GetProfileByUserId', 'LoginChild', 'GetUserProfileByUserID', 'GetKeyValuePair', 'SetKeyValuePair', 'GetKeyValuePairByUserID', 'SetKeyValuePairByUserID', 'GetUserProfile', 'GetQuestions', 'GetCommonInventory',
'GetAuthoritativeTime', 'SetAvatar', 'GetAllActivePetsByuserId', 'GetPetAchievementsByUserID', 'GetDetailedChildList', 'GetStore', 'GetAllRanks']
for method in methods: for method in methods:
if method in path: if method in path:
return True return True

View File

@ -0,0 +1,36 @@
using System.Reflection;
using Microsoft.AspNetCore.Mvc;
using sodoff.Model;
namespace sodoff.Controllers.Common;
public class AchievementController : Controller {
private readonly DBContext ctx;
public AchievementController(DBContext ctx) {
this.ctx = ctx;
}
[HttpPost]
//[Produces("application/xml")]
[Route("AchievementWebService.asmx/GetPetAchievementsByUserID")]
public IActionResult GetPetAchievementsByUserID() {
// TODO, this is a placeholder
return Ok("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<ArrayOfUserAchievementInfo xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://api.jumpstart.com/\" />");
}
[HttpPost]
//[Produces("application/xml")]
[Route("AchievementWebService.asmx/GetAllRanks")]
public IActionResult GetAllRanks() {
// TODO, this is a placeholder
var assembly = Assembly.GetExecutingAssembly();
string resourceName = assembly.GetManifestResourceNames().Single(str => str.EndsWith("allranks.xml"));
using (Stream stream = assembly.GetManifestResourceStream(resourceName))
using (StreamReader reader = new StreamReader(stream)) {
string result = reader.ReadToEnd();
return Ok(result);
}
}
}

View File

@ -109,8 +109,6 @@ public class AuthenticationController : Controller {
} }
// This is more of a "create session for viking", rather than "login child" // This is more of a "create session for viking", rather than "login child"
[HttpPost]
[Produces("application/xml")]
[Route("AuthenticationWebService.asmx/LoginChild")] [Route("AuthenticationWebService.asmx/LoginChild")]
[DecryptRequest("childUserID")] [DecryptRequest("childUserID")]
[EncryptResponse] [EncryptResponse]

View File

@ -66,7 +66,7 @@ public class ContentController : Controller {
// Get the pair // Get the pair
Model.PairData? pair = keyValueService.GetPairData(session.UserId, session.VikingId, pairId); Model.PairData? pair = keyValueService.GetPairData(session.UserId, session.VikingId, pairId);
return keyValueService.ModelToSchema(pair); return keyValueService.ModelToSchema(pair);
} }
@ -80,7 +80,7 @@ public class ContentController : Controller {
Session? session = ctx.Sessions.FirstOrDefault(s => s.ApiToken == apiToken); Session? session = ctx.Sessions.FirstOrDefault(s => s.ApiToken == apiToken);
if (session is null) if (session is null)
return Ok(false); return Ok(false);
bool result = keyValueService.SetPairData(session.UserId, session.VikingId, pairId, schemaData); bool result = keyValueService.SetPairData(session.UserId, session.VikingId, pairId, schemaData);
return Ok(result); return Ok(result);
@ -98,6 +98,7 @@ public class ContentController : Controller {
return keyValueService.ModelToSchema(pair); return keyValueService.ModelToSchema(pair);
} }
[HttpPost] [HttpPost]
[Produces("application/xml")] [Produces("application/xml")]
[Route("ContentWebService.asmx/SetKeyValuePairByUserID")] [Route("ContentWebService.asmx/SetKeyValuePairByUserID")]
@ -114,4 +115,91 @@ public class ContentController : Controller {
return Ok(result); return Ok(result);
} }
[HttpPost]
[Produces("application/xml")]
[Route("V2/ContentWebService.asmx/GetCommonInventory")]
[Route("ContentWebService.asmx/GetCommonInventory")]
public IActionResult GetCommonInventory([FromForm] string apiToken) {
// TODO, this is a placeholder
User? user = ctx.Sessions.FirstOrDefault(e => e.ApiToken == apiToken)?.User;
Viking? viking = ctx.Sessions.FirstOrDefault(e => e.ApiToken == apiToken)?.Viking;
if (user is null && viking is null) {
return Ok();
}
return Ok(new CommonInventoryData {
UserID = Guid.Parse(user is not null ? user.Id : viking.Id),
Item = new UserItemData[] {
new UserItemData {
UserInventoryID = 1099730701,
ItemID = 8977,
Quantity = 1,
Uses = -1,
ModifiedDate = DateTime.Now,
Item = new ItemData {
AssetName = "DragonStableINTDO",
Cost = 100000,
CashCost = -1,
CreativePoints = 0,
Description = "Any dragon would be glad to make one of the two available nests home!",
IconName = "RS_DATA/DragonsStablesDO.unity3d/IcoDWDragonStableDefault",
InventoryMax = 1,
ItemID = 8977,
ItemName = "Dragon Stable",
Locked = false,
Stackable = false,
AllowStacking = false,
SaleFactor = 10,
Uses = -1,
Attribute = new ItemAttribute[] {
new ItemAttribute { Key = "2D", Value = "1" },
new ItemAttribute { Key = "NestCount", Value = "2" },
new ItemAttribute { Key = "StableType", Value = "All" }
},
Category = new ItemDataCategory[] {
new ItemDataCategory { CategoryId = 455, CategoryName = "Dragons Dragon Stable", IconName = "8977"}
}
}
}
}
});
}
[HttpPost]
[Produces("application/xml")]
[Route("ContentWebService.asmx/GetAuthoritativeTime")]
public IActionResult GetAuthoritativeTime() {
return Ok(new DateTime(DateTime.Now.Ticks));
}
[HttpPost]
[Produces("application/xml")]
[Route("V2/ContentWebService.asmx/SetAvatar")]
public IActionResult SetAvatar([FromForm] string apiToken, [FromForm] string contentXML) {
Viking? viking = ctx.Sessions.FirstOrDefault(e => e.ApiToken == apiToken)?.Viking;
if (viking is null) {
return Ok(new SetAvatarResult {
Success = false,
StatusCode = AvatarValidationResult.Error
});
}
viking.AvatarSerialized = contentXML;
ctx.SaveChanges();
return Ok(new SetAvatarResult {
Success = true,
DisplayName = viking.Name,
StatusCode = AvatarValidationResult.Valid
});
}
[HttpPost]
//[Produces("application/xml")]
[Route("V2/ContentWebService.asmx/GetAllActivePetsByuserId")]
public IActionResult GetAllActivePetsByuserId() {
// TODO, this is a placeholder
return Ok("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<ArrayOfRaisedPetData xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:nil=\"true\" />");
}
} }

View File

@ -0,0 +1,28 @@
using System.Reflection;
using Microsoft.AspNetCore.Mvc;
using sodoff.Model;
namespace sodoff.Controllers.Common;
public class ItemStoreController : Controller {
private readonly DBContext ctx;
public ItemStoreController(DBContext ctx) {
this.ctx = ctx;
}
[HttpPost]
//[Produces("application/xml")]
[Route("ItemStoreWebService.asmx/GetStore")]
public IActionResult GetStore() {
// TODO, this may be implemented enough, but may not be
var assembly = Assembly.GetExecutingAssembly();
string resourceName = assembly.GetManifestResourceNames().Single(str => str.EndsWith("store.xml"));
using (Stream stream = assembly.GetManifestResourceStream(resourceName))
using (StreamReader reader = new StreamReader(stream)) {
string result = reader.ReadToEnd();
return Ok(result);
}
}
}

View File

@ -1,5 +1,5 @@
using Microsoft.AspNetCore.Mvc; using System.Reflection;
using sodoff.Attributes; using Microsoft.AspNetCore.Mvc;
using sodoff.Model; using sodoff.Model;
using sodoff.Schema; using sodoff.Schema;
using sodoff.Util; using sodoff.Util;
@ -23,34 +23,143 @@ public class ProfileController : Controller {
} }
Viking? viking = ctx.Vikings.FirstOrDefault(e => e.Id == userId); Viking? viking = ctx.Vikings.FirstOrDefault(e => e.Id == userId);
return Ok(GetProfileDataFromViking(viking));
}
return Ok(new UserProfileData { [HttpPost]
ID = viking.Id, [Produces("application/xml")]
AvatarInfo = new AvatarDisplayData { [Route("ProfileWebService.asmx/GetUserProfile")]
UserInfo = new UserInfo { public IActionResult GetUserProfile([FromForm] string apiToken) {
UserID = viking.Id, Viking? viking = ctx.Sessions.FirstOrDefault(e => e.ApiToken == apiToken)?.Viking;
ParentUserID = user.Id, User? user = viking?.User;
Username = viking.Name, if (user is null || viking is null) {
MultiplayerEnabled = true, // TODO: what response for not logged in?
GenderID = Gender.Male, return Ok();
OpenChatEnabled = true, }
CreationDate = DateTime.Now
}, return Ok(GetProfileDataFromViking(viking));
UserSubscriptionInfo = new UserSubscriptionInfo { SubscriptionTypeID = 2 }, // TODO: figure out what this is }
Achievements = new UserAchievementInfo[] {
new UserAchievementInfo { [HttpPost]
UserID = Guid.Parse(viking.Id), [Produces("application/xml")]
AchievementPointTotal = 0, [Route("ProfileWebService.asmx/GetDetailedChildList")]
RankID = 1, public Schema.UserProfileDataList? GetDetailedChildList([FromForm] string parentApiToken) {
PointTypeID = 1, // TODO: what is this? User? user = ctx.Sessions.FirstOrDefault(e => e.ApiToken == parentApiToken)?.User;
if (user is null)
// TODO: what response for not logged in?
return null;
if (user.Vikings.Count <= 0)
return null;
UserProfileData[] profiles = user.Vikings.Select(GetProfileDataFromViking).ToArray();
return new UserProfileDataList {
UserProfiles = profiles
};
}
[HttpPost]
[Produces("application/xml")]
[Route("ProfileWebService.asmx/GetQuestions")]
public IActionResult GetQuestions([FromForm] string apiToken) {
return Ok(new ProfileQuestionData {
Lists = new ProfileQuestionList[] {
new ProfileQuestionList {
ID = 4,
Questions = new ProfileQuestion[] {
new ProfileQuestion {
CategoryID = 3,
IsActive = "true", // this is a string, which makes me sad
Locale = "en-US",
Ordinal = 1,
ID = 48,
DisplayText = "How Did You Hear About US ?",
Answers = new ProfileAnswer[] {
new ProfileAnswer {
ID = 320,
DisplayText = "TV Commercial",
Locale = "en-US",
Ordinal = 1,
QuestionID = 48
},
new ProfileAnswer {
ID = 324,
DisplayText = "I bought the RIders Of Berk DVD",
Locale = "en-US",
Ordinal = 5,
QuestionID = 48
},
new ProfileAnswer {
ID = 325,
DisplayText = "I bought the Defenders of Berk DVD",
Locale = "en-US",
Ordinal = 6,
QuestionID = 48
}
}
}
} }
} }
}
});
}
private UserProfileData GetProfileDataFromViking(Viking viking) {
// Get the avatar data
AvatarData avatarData = null;
if (viking.AvatarSerialized is not null) {
avatarData = XmlUtil.DeserializeXml<AvatarData>(viking.AvatarSerialized);
}
// Build the AvatarDisplayData
AvatarDisplayData avatar = new AvatarDisplayData {
AvatarData = avatarData,
UserInfo = new UserInfo {
MembershipID = "ef84db9-59c6-4950-b8ea-bbc1521f899b", // placeholder
UserID = viking.Id,
ParentUserID = viking.UserId,
Username = viking.Name,
FirstName = viking.Name,
MultiplayerEnabled = true,
Locale = "en-US", // placeholder
GenderID = Gender.Male, // placeholder
OpenChatEnabled = true,
IsApproved = true,
RegistrationDate = new DateTime(DateTime.Now.Ticks), // placeholder
CreationDate = new DateTime(DateTime.Now.Ticks), // placeholder
FacebookUserID = 0
}, },
UserSubscriptionInfo = new UserSubscriptionInfo {
UserID = viking.UserId,
MembershipID = 130687131, // placeholder
SubscriptionTypeID = 2, // placeholder
SubscriptionDisplayName = "NonMember", // placeholder
SubscriptionPlanID = 41, // placeholder
SubscriptionID = -3, // placeholder
IsActive = false, // placeholder
},
RankID = 0, // placeholder
AchievementInfo = null, // placeholder
Achievements = new UserAchievementInfo[] {
new UserAchievementInfo {
UserID = Guid.Parse(viking.Id),
AchievementPointTotal = 0, // placeholder
RankID = 1, // placeholder
PointTypeID = 1 // placeholder
}
}
};
return new UserProfileData {
ID = viking.Id,
AvatarInfo = avatar,
AchievementCount = 0, AchievementCount = 0,
MythieCount = 0, MythieCount = 0,
AnswerData = new UserAnswerData { UserID = viking.Id }, AnswerData = new UserAnswerData { UserID = viking.Id },
GameCurrency = 0, GameCurrency = 300,
CashCurrency = 0 CashCurrency = 75,
}); ActivityCount = 0,
UserGradeData = new UserGrade { UserGradeID = 0 }
};
} }
} }

View File

@ -31,6 +31,13 @@ public class DBContext : DbContext {
builder.Entity<Viking>().HasMany(u => u.Sessions) builder.Entity<Viking>().HasMany(u => u.Sessions)
.WithOne(e => e.Viking); .WithOne(e => e.Viking);
builder.Entity<Viking>().HasOne(s => s.User)
.WithMany(e => e.Vikings)
.HasForeignKey(e => e.UserId);
builder.Entity<User>().HasMany(u => u.Vikings)
.WithOne(e => e.User);
builder.Entity<PairData>() builder.Entity<PairData>()
.HasKey(e => e.Id); .HasKey(e => e.Id);

View File

@ -15,4 +15,6 @@ public class User {
public string Password { get; set; } = null!; public string Password { get; set; } = null!;
public virtual ICollection<Session> Sessions { get; set; } = null!; public virtual ICollection<Session> Sessions { get; set; } = null!;
public virtual ICollection<Viking> Vikings { get; set; } = null!;
} }

View File

@ -11,6 +11,8 @@ public class Viking {
[Required] [Required]
public string UserId { get; set; } = null!; public string UserId { get; set; } = null!;
public string? AvatarSerialized { get; set; }
public virtual ICollection<Session> Sessions { get; set; } = null!; public virtual ICollection<Session> Sessions { get; set; } = null!;
public virtual User User { get; set; } = null!; public virtual User User { get; set; } = null!;

2368
src/Resources/allranks.xml Normal file

File diff suppressed because it is too large Load Diff

70419
src/Resources/store.xml Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,47 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "AR", Namespace = "")]
[Serializable]
public class AchievementReward
{
[XmlElement(ElementName = "ui", IsNullable = true)]
public UserItemData UserItem { get; set; }
[XmlElement(ElementName = "a")]
public int? Amount;
[XmlElement(ElementName = "p", IsNullable = true)]
public int? PointTypeID;
[XmlElement(ElementName = "ii")]
public int ItemID;
[XmlElement(ElementName = "i", IsNullable = true)]
public Guid? EntityID;
[XmlElement(ElementName = "t")]
public int EntityTypeID;
[XmlElement(ElementName = "r")]
public int RewardID;
[XmlElement(ElementName = "ai")]
public int AchievementID;
[XmlElement(ElementName = "amulti")]
public bool AllowMultiple;
[XmlElement(ElementName = "mina", IsNullable = true)]
public int? MinAmount;
[XmlElement(ElementName = "maxa", IsNullable = true)]
public int? MaxAmount;
[XmlElement(ElementName = "d", IsNullable = true)]
public DateTime? Date;
[XmlElement(ElementName = "cid")]
public int CommonInventoryID;
}

View File

@ -0,0 +1,39 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
public enum AvatarValidationResult
{
[XmlEnum("1")]
Valid = 1,
[XmlEnum("2")]
PartInvalid,
[XmlEnum("3")]
PartTypeDuplicate,
[XmlEnum("4")]
PartTypeEmpty,
[XmlEnum("5")]
PartTypeLengthInvalid,
[XmlEnum("6")]
TexturesInvalid,
[XmlEnum("7")]
GeometriesInvalid,
[XmlEnum("8")]
OffsetsInvalid,
[XmlEnum("9")]
OffsetsNotFloat,
[XmlEnum("10")]
AvatarDisplayNameInvalid,
[XmlEnum("255")]
Error = 255
}

18
src/Schema/BluePrint.cs Normal file
View File

@ -0,0 +1,18 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "BP", Namespace = "", IsNullable = true)]
[Serializable]
public class BluePrint
{
[XmlElement(ElementName = "BPDC", IsNullable = true)]
public List<BluePrintDeductibleConfig> Deductibles { get; set; }
[XmlElement(ElementName = "ING", IsNullable = false)]
public List<BluePrintSpecification> Ingredients { get; set; }
[XmlElement(ElementName = "OUT", IsNullable = false)]
public List<BluePrintSpecification> Outputs { get; set; }
}

View File

@ -0,0 +1,20 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "BPDC", Namespace = "", IsNullable = true)]
[Serializable]
public class BluePrintDeductibleConfig
{
[XmlElement(ElementName = "BPIID", IsNullable = false)]
public int BluePrintItemID { get; set; }
[XmlElement(ElementName = "DT", IsNullable = false)]
public DeductibleType DeductibleType { get; set; }
[XmlElement(ElementName = "IID", IsNullable = true)]
public int? ItemID { get; set; }
[XmlElement(ElementName = "QTY", IsNullable = false)]
public int Quantity { get; set; }
}

View File

@ -0,0 +1,30 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
public class BluePrintSpecification
{
[XmlElement(ElementName = "BPSID", IsNullable = false)]
public int BluePrintSpecID { get; set; }
[XmlElement(ElementName = "BPIID", IsNullable = false)]
public int BluePrintItemID { get; set; }
[XmlElement(ElementName = "IID", IsNullable = true)]
public int? ItemID { get; set; }
[XmlElement(ElementName = "CID", IsNullable = true)]
public int? CategoryID { get; set; }
[XmlElement(ElementName = "IR", IsNullable = true)]
public ItemRarity? ItemRarity { get; set; }
[XmlElement(ElementName = "T", IsNullable = true)]
public ItemTier? Tier { get; set; }
[XmlElement(ElementName = "QTY", IsNullable = false)]
public int Quantity { get; set; }
[XmlElement(ElementName = "ST", IsNullable = false)]
public SpecificationType SpecificationType { get; set; }
}

View File

@ -0,0 +1,14 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "CI", Namespace = "")]
[Serializable]
public class CommonInventoryData
{
[XmlElement(ElementName = "uid")]
public Guid UserID;
[XmlElement(ElementName = "i")]
public UserItemData[] Item;
}

View File

@ -0,0 +1,10 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[Serializable]
public class CompletionAction
{
[XmlElement(ElementName = "Transition")]
public StateTransition Transition;
}

View File

@ -0,0 +1,20 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "DT")]
[Serializable]
public enum DataTypeInfo
{
[XmlEnum("I")]
Int = 1,
[XmlEnum("2")]
Float,
[XmlEnum("3")]
Double,
[XmlEnum("4")]
String
}

View File

@ -0,0 +1,10 @@
using System;
namespace sodoff.Schema;
public enum DeductibleType
{
Coins = 1,
VCash,
Item
}

View File

@ -0,0 +1,14 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "AT", Namespace = "")]
[Serializable]
public class ItemAttribute
{
[XmlElement(ElementName = "k")]
public string Key;
[XmlElement(ElementName = "v")]
public string Value;
}

View File

@ -0,0 +1,14 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "Availability", Namespace = "")]
[Serializable]
public class ItemAvailability
{
[XmlElement(ElementName = "sdate", IsNullable = true)]
public DateTime? StartDate;
[XmlElement(ElementName = "edate", IsNullable = true)]
public DateTime? EndDate;
}

100
src/Schema/ItemData.cs Normal file
View File

@ -0,0 +1,100 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "I", Namespace = "", IsNullable = true)]
public class ItemData
{
[XmlElement(ElementName = "is")]
public List<ItemState> ItemStates { get; set; }
[XmlElement(ElementName = "ir", IsNullable = true)]
public ItemRarity? ItemRarity { get; set; }
[XmlElement(ElementName = "ipsm", IsNullable = true)]
public ItemPossibleStatsMap PossibleStatsMap { get; set; }
[XmlElement(ElementName = "ism", IsNullable = true)]
public ItemStatsMap ItemStatsMap { get; set; }
[XmlElement(ElementName = "iscs", IsNullable = true)]
public ItemSaleConfig[] ItemSaleConfigs { get; set; }
[XmlElement(ElementName = "bp", IsNullable = true)]
public BluePrint BluePrint { get; set; }
[XmlElement(ElementName = "an")]
public string AssetName;
[XmlElement(ElementName = "at", IsNullable = true)]
public ItemAttribute[] Attribute;
[XmlElement(ElementName = "c")]
public ItemDataCategory[] Category;
[XmlElement(ElementName = "ct")]
public int Cost;
[XmlElement(ElementName = "ct2")]
public int CashCost;
[XmlElement(ElementName = "cp")]
public int CreativePoints;
[XmlElement(ElementName = "d")]
public string Description;
[XmlElement(ElementName = "icn")]
public string IconName;
[XmlElement(ElementName = "im")]
public int InventoryMax;
[XmlElement(ElementName = "id")]
public int ItemID;
[XmlElement(ElementName = "itn")]
public string ItemName;
[XmlElement(ElementName = "itnp")]
public string ItemNamePlural;
[XmlElement(ElementName = "l")]
public bool Locked;
[XmlElement(ElementName = "g", IsNullable = true)]
public string Geometry2;
[XmlElement(ElementName = "ro", IsNullable = true)]
public ItemDataRollover Rollover;
[XmlElement(ElementName = "rid", IsNullable = true)]
public int? RankId;
[XmlElement(ElementName = "r")]
public ItemDataRelationship[] Relationship;
[XmlElement(ElementName = "s")]
public bool Stackable;
[XmlElement(ElementName = "as")]
public bool AllowStacking;
[XmlElement(ElementName = "sf")]
public int SaleFactor;
[XmlElement(ElementName = "t")]
public ItemDataTexture[] Texture;
[XmlElement(ElementName = "u")]
public int Uses;
[XmlElement(ElementName = "av")]
public ItemAvailability[] Availability;
[XmlElement(ElementName = "rtid")]
public int RewardTypeID;
[XmlElement(ElementName = "p", IsNullable = true)]
public int? Points;
}

View File

@ -0,0 +1,17 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "IC", Namespace = "")]
[Serializable]
public class ItemDataCategory
{
[XmlElement(ElementName = "cid")]
public int CategoryId;
[XmlElement(ElementName = "cn")]
public string CategoryName;
[XmlElement(ElementName = "i", IsNullable = true)]
public string IconName;
}

View File

@ -0,0 +1,20 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "IRE", Namespace = "")]
[Serializable]
public class ItemDataRelationship
{
[XmlElement(ElementName = "t")]
public string Type;
[XmlElement(ElementName = "id")]
public int ItemId;
[XmlElement(ElementName = "wt")]
public int Weight;
[XmlElement(ElementName = "q")]
public int Quantity;
}

View File

@ -0,0 +1,14 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "IRO", Namespace = "")]
[Serializable]
public class ItemDataRollover
{
[XmlElement(ElementName = "d")]
public string DialogName;
[XmlElement(ElementName = "b")]
public string Bundle;
}

View File

@ -0,0 +1,20 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "IT", Namespace = "")]
[Serializable]
public class ItemDataTexture
{
[XmlElement(ElementName = "n")]
public string TextureName;
[XmlElement(ElementName = "t")]
public string TextureTypeName;
[XmlElement(ElementName = "x", IsNullable = true)]
public float? OffsetX;
[XmlElement(ElementName = "y", IsNullable = true)]
public float? OffsetY;
}

View File

@ -0,0 +1,20 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "IPSM", Namespace = "", IsNullable = false)]
[Serializable]
public class ItemPossibleStatsMap
{
[XmlElement(ElementName = "IID", IsNullable = false)]
public int ItemID { get; set; }
[XmlElement(ElementName = "SC", IsNullable = false)]
public int ItemStatsCount { get; set; }
[XmlElement(ElementName = "SID", IsNullable = false)]
public int SetID { get; set; }
[XmlElement(ElementName = "SS", IsNullable = false)]
public List<Stat> Stats { get; set; }
}

23
src/Schema/ItemRarity.cs Normal file
View File

@ -0,0 +1,23 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "IR")]
[Serializable]
public enum ItemRarity
{
[XmlEnum("0")]
NonBattleCommon,
[XmlEnum("1")]
Common,
[XmlEnum("2")]
Rare,
[XmlEnum("3")]
Epic,
[XmlEnum("4")]
Legendary
}

View File

@ -0,0 +1,23 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "ISC", Namespace = "", IsNullable = true)]
[Serializable]
public class ItemSaleConfig
{
[XmlElement(ElementName = "IID", IsNullable = true)]
public int? ItemID { get; set; }
[XmlElement(ElementName = "CID", IsNullable = true)]
public int? CategoryID { get; set; }
[XmlElement(ElementName = "RID", IsNullable = true)]
public int? RarityID { get; set; }
[XmlElement(ElementName = "QTY", IsNullable = false)]
public int Quantity { get; set; }
[XmlElement(ElementName = "RIID", IsNullable = false)]
public int RewardItemID { get; set; }
}

20
src/Schema/ItemStat.cs Normal file
View File

@ -0,0 +1,20 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "IS", Namespace = "")]
[Serializable]
public class ItemStat
{
[XmlElement(ElementName = "ID")]
public int ItemStatID { get; set; }
[XmlElement(ElementName = "N")]
public string Name { get; set; }
[XmlElement(ElementName = "V")]
public string Value { get; set; }
[XmlElement(ElementName = "DTI")]
public DataTypeInfo DataType { get; set; }
}

26
src/Schema/ItemState.cs Normal file
View File

@ -0,0 +1,26 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "ItemState", Namespace = "")]
[Serializable]
public class ItemState
{
[XmlElement(ElementName = "ItemStateID")]
public int ItemStateID;
[XmlElement(ElementName = "Name")]
public string Name;
[XmlElement(ElementName = "Rule")]
public ItemStateRule Rule;
[XmlElement(ElementName = "Order")]
public int Order;
[XmlElement(ElementName = "AchievementID", IsNullable = true)]
public int? AchievementID;
[XmlElement(ElementName = "Rewards")]
public AchievementReward[] Rewards;
}

View File

@ -0,0 +1,17 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "ItemStateCriteria", Namespace = "")]
[XmlInclude(typeof(ItemStateCriteriaLength))]
[XmlInclude(typeof(ItemStateCriteriaConsumable))]
[XmlInclude(typeof(ItemStateCriteriaReplenishable))]
[XmlInclude(typeof(ItemStateCriteriaOverride))]
[XmlInclude(typeof(ItemStateCriteriaSpeedUpItem))]
[XmlInclude(typeof(ItemStateCriteriaExpiry))]
[Serializable]
public class ItemStateCriteria
{
[XmlElement(ElementName = "Type")]
public ItemStateCriteriaType Type;
}

View File

@ -0,0 +1,17 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "ItemStateCriteriaConsumable", Namespace = "")]
[Serializable]
public class ItemStateCriteriaConsumable : ItemStateCriteria
{
[XmlElement(ElementName = "ItemID")]
public int ItemID;
[XmlElement(ElementName = "ConsumeUses")]
public bool ConsumeUses;
[XmlElement(ElementName = "Amount")]
public int Amount;
}

View File

@ -0,0 +1,14 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "ItemStateCriteriaExpiry", Namespace = "")]
[Serializable]
public class ItemStateCriteriaExpiry : ItemStateCriteria
{
[XmlElement(ElementName = "Period")]
public int Period;
[XmlElement(ElementName = "EndStateID")]
public int EndStateID;
}

View File

@ -0,0 +1,11 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "ItemStateCriteriaLength", Namespace = "")]
[Serializable]
public class ItemStateCriteriaLength : ItemStateCriteria
{
[XmlElement(ElementName = "Period")]
public int Period;
}

View File

@ -0,0 +1,17 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "ItemStateCriteriaOverride", Namespace = "")]
[Serializable]
public class ItemStateCriteriaOverride : ItemStateCriteria
{
[XmlElement(ElementName = "ItemID")]
public int ItemID { get; set; }
[XmlElement(ElementName = "ConsumeUses")]
public bool ConsumeUses { get; set; }
[XmlElement(ElementName = "Amount")]
public int Amount { get; set; }
}

View File

@ -0,0 +1,17 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "ItemStateCriteriaReplenishable", Namespace = "")]
[Serializable]
public class ItemStateCriteriaReplenishable : ItemStateCriteria
{
[XmlElement(ElementName = "ApplyRank")]
public bool ApplyRank;
[XmlElement(ElementName = "PointTypeID", IsNullable = true)]
public int? PointTypeID;
[XmlElement(ElementName = "ReplenishableRates")]
public List<ReplenishableRate> ReplenishableRates;
}

View File

@ -0,0 +1,28 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "ItemStateCriteriaSpeedUpItem", Namespace = "")]
public class ItemStateCriteriaSpeedUpItem : ItemStateCriteria
{
[XmlElement(ElementName = "ItemID")]
public int ItemID { get; set; }
[XmlElement(ElementName = "ConsumeUses")]
public bool ConsumeUses { get; set; }
[XmlElement(ElementName = "Amount")]
public int Amount { get; set; }
[XmlElement(ElementName = "ChangeState")]
public bool ChangeState { get; set; }
[XmlElement(ElementName = "EndStateID")]
public int EndStateID { get; set; }
[XmlElement(ElementName = "SpeedUpCapacity")]
public int SpeedUpCapacity { get; set; }
[XmlElement(ElementName = "SpeedUpUses")]
public bool SpeedUpUses { get; set; }
}

View File

@ -0,0 +1,22 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[Serializable]
public enum ItemStateCriteriaType
{
[XmlEnum("1")]
Length = 1,
[XmlEnum("2")]
ConsumableItem,
[XmlEnum("3")]
ReplenishableItem,
[XmlEnum("4")]
SpeedUpItem,
[XmlEnum("5")]
StateExpiry
}

View File

@ -0,0 +1,14 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "ItemStateRule", Namespace = "")]
[Serializable]
public class ItemStateRule
{
[XmlElement(ElementName = "Criterias")]
public List<ItemStateCriteria> Criterias;
[XmlElement(ElementName = "CompletionAction")]
public CompletionAction CompletionAction;
}

View File

@ -0,0 +1,17 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "ISM", Namespace = "", IsNullable = false)]
[Serializable]
public class ItemStatsMap
{
[XmlElement(ElementName = "IID", IsNullable = false)]
public int ItemID { get; set; }
[XmlElement(ElementName = "IT", IsNullable = false)]
public ItemTier ItemTier { get; set; }
[XmlElement(ElementName = "ISS", IsNullable = false)]
public ItemStat[] ItemStats { get; set; }
}

20
src/Schema/ItemTier.cs Normal file
View File

@ -0,0 +1,20 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "IT")]
[Serializable]
public enum ItemTier
{
[XmlEnum("1")]
Tier1 = 1,
[XmlEnum("2")]
Tier2,
[XmlEnum("3")]
Tier3,
[XmlEnum("4")]
Tier4
}

View File

@ -1,16 +1,17 @@
using System.Xml.Serialization; using System.Xml.Serialization;
namespace sodoff.Schema; namespace sodoff.Schema;
[XmlRoot(ElementName = "Pair", Namespace = "")] [XmlRoot(ElementName = "Pair", Namespace = "")]
[Serializable] [Serializable]
public class Pair { public class Pair
[XmlElement(ElementName = "PairKey")] {
public string PairKey; [XmlElement(ElementName = "PairKey")]
public string PairKey;
[XmlElement(ElementName = "PairValue")]
public string PairValue; [XmlElement(ElementName = "PairValue")]
public string PairValue;
[XmlElement(ElementName = "UpdateDate")]
public DateTime UpdateDate; [XmlElement(ElementName = "UpdateDate")]
} public DateTime UpdateDate;
}

View File

@ -7,6 +7,4 @@ namespace sodoff.Schema;
public class PairData { public class PairData {
[XmlElement("Pair", IsNullable = true)] [XmlElement("Pair", IsNullable = true)]
public Pair[] Pairs { get; set; } public Pair[] Pairs { get; set; }
} }

View File

@ -0,0 +1,26 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "Answers", IsNullable = true, Namespace = "")]
[Serializable]
public class ProfileAnswer
{
[XmlElement(ElementName = "ID")]
public int ID;
[XmlElement(ElementName = "T")]
public string DisplayText;
[XmlElement(ElementName = "Img")]
public string ImageURL;
[XmlElement(ElementName = "L")]
public string Locale;
[XmlElement(ElementName = "O")]
public int Ordinal;
[XmlElement(ElementName = "QID")]
public int QuestionID;
}

View File

@ -0,0 +1,32 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "Qs", IsNullable = true, Namespace = "")]
[Serializable]
public class ProfileQuestion
{
[XmlElement(ElementName = "CID", IsNullable = false)]
public int CategoryID;
[XmlElement(ElementName = "Img")]
public string ImageURL;
[XmlElement(ElementName = "A")]
public string IsActive;
[XmlElement(ElementName = "L")]
public string Locale;
[XmlElement(ElementName = "Ord")]
public int Ordinal;
[XmlElement(ElementName = "ID")]
public int ID;
[XmlElement(ElementName = "T")]
public string DisplayText;
[XmlElement(ElementName = "Answers")]
public ProfileAnswer[] Answers;
}

View File

@ -0,0 +1,31 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "QuestionData", IsNullable = true, Namespace = "")]
[Serializable]
public class ProfileQuestionData
{
[XmlElement(ElementName = "QL")]
public ProfileQuestionList[] Lists;
public const int ANSWER_BOY = 227;
public const int ANSWER_GIRL = 228;
public const int ANSWER_UNKNOWN = 229;
public const int ANSWER_TRUE = 32;
public const int ANSWER_FALSE = 33;
public const int COUNTRY_QUESTIONS = 33;
public const int GENDER_QUESTIONS = 32;
public const int LIST_ID_FAVORITES = 1;
public const int LIST_ID_STATUS = 2;
public const int LIST_ID_GROUPS = 3;
}

View File

@ -0,0 +1,18 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "QL", IsNullable = true, Namespace = "")]
[Serializable]
public class ProfileQuestionList
{
[XmlElement(ElementName = "ID", IsNullable = false)]
public int ID;
[XmlElement(ElementName = "Qs")]
public ProfileQuestion[] Questions;
public string Name;
public string ImageURL;
}

View File

@ -0,0 +1,20 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "ReplenishableRate", Namespace = "")]
[Serializable]
public class ReplenishableRate
{
[XmlElement(ElementName = "Uses")]
public int Uses;
[XmlElement(ElementName = "Rate")]
public double Rate;
[XmlElement(ElementName = "MaxUses")]
public int MaxUses;
[XmlElement(ElementName = "Rank", IsNullable = true)]
public int? Rank;
}

View File

@ -0,0 +1,20 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "SetAvatarResult", Namespace = "", IsNullable = false)]
[Serializable]
public class SetAvatarResult
{
[XmlElement(ElementName = "Success")]
public bool Success { get; set; }
[XmlElement(ElementName = "StatusCode")]
public AvatarValidationResult StatusCode { get; set; }
[XmlElement(ElementName = "DisplayName", IsNullable = true)]
public string DisplayName { get; set; }
[XmlElement(ElementName = "Suggestions", IsNullable = true)]
public SuggestionResult Suggestions { get; set; }
}

View File

@ -0,0 +1,9 @@
using System;
namespace sodoff.Schema;
public enum SpecificationType
{
Ingredient = 1,
Output
}

23
src/Schema/Stat.cs Normal file
View File

@ -0,0 +1,23 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "STAT", Namespace = "", IsNullable = false)]
[Serializable]
public class Stat
{
[XmlElement(ElementName = "IID", IsNullable = false)]
public int ItemID { get; set; }
[XmlElement(ElementName = "ISID", IsNullable = false)]
public int ItemStatsID { get; set; }
[XmlElement(ElementName = "SID", IsNullable = false)]
public int SetID { get; set; }
[XmlElement(ElementName = "PROB", IsNullable = false)]
public int Probability { get; set; }
[XmlElement(ElementName = "ISRM", IsNullable = false)]
public List<StatRangeMap> ItemStatsRangeMaps { get; set; }
}

View File

@ -0,0 +1,23 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "SRM", Namespace = "", IsNullable = false)]
[Serializable]
public class StatRangeMap
{
[XmlElement(ElementName = "ISID", IsNullable = false)]
public int ItemStatsID { get; set; }
[XmlElement(ElementName = "ISN", IsNullable = false)]
public string ItemStatsName { get; set; }
[XmlElement(ElementName = "ITID", IsNullable = false)]
public int ItemTierID { get; set; }
[XmlElement(ElementName = "SR", IsNullable = false)]
public int StartRange { get; set; }
[XmlElement(ElementName = "ER", IsNullable = false)]
public int EndRange { get; set; }
}

View File

@ -0,0 +1,22 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[Serializable]
public enum StateTransition
{
[XmlEnum("1")]
NextState = 1,
[XmlEnum("2")]
Completion,
[XmlEnum("3")]
Deletion,
[XmlEnum("4")]
InitialState,
[XmlEnum("5")]
Expired
}

View File

@ -0,0 +1,38 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "UserItem", Namespace = "")]
[Serializable]
public class UserItemData
{
[XmlElement(ElementName = "iid")]
public int ItemID { get; set; }
[XmlElement(ElementName = "md", IsNullable = true)]
public DateTime? ModifiedDate { get; set; }
[XmlElement(ElementName = "uia", IsNullable = true)]
public PairData UserItemAttributes { get; set; }
[XmlElement(ElementName = "iss", IsNullable = true)]
public ItemStat[] ItemStats { get; set; }
[XmlElement(ElementName = "IT", IsNullable = true)]
public ItemTier? ItemTier { get; set; }
[XmlElement(ElementName = "cd", IsNullable = true)]
public DateTime? CreatedDate { get; set; }
[XmlElement(ElementName = "uiid")]
public int UserInventoryID;
[XmlElement(ElementName = "q")]
public int Quantity;
[XmlElement(ElementName = "u")]
public int Uses;
[XmlElement(ElementName = "i")]
public ItemData Item;
}

View File

@ -0,0 +1,11 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "ArrayOfUserProfileDisplayData")]
[Serializable]
public class UserProfileDataList
{
[XmlElement(ElementName = "UserProfileDisplayData")]
public UserProfileData[] UserProfiles;
}

View File

@ -7,4 +7,12 @@ public class XmlUtil {
using (var reader = new StringReader(xmlString)) using (var reader = new StringReader(xmlString))
return (T)serializer.Deserialize(reader); return (T)serializer.Deserialize(reader);
} }
public static string SerializeXml<T>(T xmlObject) {
var serializer = new XmlSerializer(typeof(T));
using (var writer = new StringWriter()) {
serializer.Serialize(writer, xmlObject);
return writer.ToString();
}
}
} }

View File

@ -11,4 +11,24 @@
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.7" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.7" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<None Remove="Resources\store.xml" />
<None Remove="Resources\allranks.xml" />
</ItemGroup>
<ItemGroup>
<None Update="Resources\childlist.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Resources\store.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Resources\store.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="Resources\allranks.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</EmbeddedResource>
</ItemGroup>
</Project> </Project>