implement dragons

pets, which are dragons in SoD
This commit is contained in:
hictooth 2023-06-21 20:57:43 +01:00
parent be9d3a0026
commit 5f7921ea6f
28 changed files with 748 additions and 9 deletions

3
.gitignore vendored
View File

@ -5,4 +5,5 @@ src/bin
src/obj
src/sodoff.db
src/sodoff.db-shm
src/sodoff.db-wal
src/sodoff.db-wal
__pycache__/

View File

@ -45,12 +45,17 @@ Then run School of Dragons.
- SetAvatar
- RegisterParent
- RegisterChild
- SetRaisedPet
- GetAllActivePetsByuserId
- SetImage
- GetImage
#### Implemented enough (probably)
- GetRules (doesn't return any rules, probably doesn't need to)
- GetQuestions (doesn't return all questions, probably doesn't need to)
- GetSubscriptionInfo (always returns member, with end date 10 years from now)
- SetTaskState (only the TaskCanBeDone status is supported)
- CreatePet (doesn't handle SetAsSelectedPet/UnSelectOtherPets)
#### Partially implemented
- GetUserProfileByUserID (a lot is still placeholder)
@ -64,7 +69,6 @@ Then run School of Dragons.
- GetStore (needs to filter out stores from request)
- GetAllRanks (needs to be populated with what ranks the user has)
- GetCommonInventory
- GetAllActivePetsByuserId (always returns null)
- GetPetAchievementsByUserId (always returns null)
- GetUserUpcomingMissionState (returns no missions)
- GetUserCompletedMissionState (returns no missions)

View File

@ -1,10 +1,44 @@
from mitmproxy import ctx
import mitmproxy.http
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',
'GetUserUpcomingMissionState',
'GetUserActiveMissionState',
'GetUserCompletedMissionState',
'SetTaskState',
'CreatePet',
'SetRaisedPet',
'SetImage',
'GetImage'
]
def routable(path):
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', 'GetUserUpcomingMissionState', 'GetUserActiveMissionState', 'GetUserCompletedMissionState', 'SetTaskState']
for method in methods:
if method in path:
return True

View File

@ -5,6 +5,7 @@ using sodoff.Model;
using sodoff.Schema;
using sodoff.Services;
using sodoff.Util;
using System;
namespace sodoff.Controllers.Common;
public class ContentController : Controller {
@ -196,11 +197,186 @@ public class ContentController : Controller {
}
[HttpPost]
//[Produces("application/xml")]
[Produces("application/xml")]
[Route("V2/ContentWebService.asmx/CreatePet")]
public IActionResult CreatePet([FromForm] string apiToken, [FromForm] string request) {
Viking? viking = ctx.Sessions.FirstOrDefault(e => e.ApiToken == apiToken)?.Viking;
if (viking is null) {
// TODO: result for invalid session
return Ok();
}
RaisedPetRequest raisedPetRequest = XmlUtil.DeserializeXml<RaisedPetRequest>(request);
// TODO: Investigate SetAsSelectedPet and UnSelectOtherPets - they don't seem to do anything
// Update the RaisedPetData with the info
String dragonId = Guid.NewGuid().ToString();
raisedPetRequest.RaisedPetData.IsPetCreated = true;
raisedPetRequest.RaisedPetData.RaisedPetID = 0; // Initially make zero, so the db auto-fills
raisedPetRequest.RaisedPetData.EntityID = Guid.Parse(dragonId);
raisedPetRequest.RaisedPetData.Name = string.Concat("Dragon-", dragonId.AsSpan(0, 8)); // Start off with a random name
raisedPetRequest.RaisedPetData.IsSelected = false; // The api returns false, not sure why
raisedPetRequest.RaisedPetData.CreateDate = new DateTime(DateTime.Now.Ticks);
raisedPetRequest.RaisedPetData.UpdateDate = new DateTime(DateTime.Now.Ticks);
// Save the dragon in the db
Dragon dragon = new Dragon {
EntityId = Guid.NewGuid().ToString(),
Viking = viking,
RaisedPetData = XmlUtil.SerializeXml(raisedPetRequest.RaisedPetData),
};
ctx.Dragons.Add(dragon);
ctx.SaveChanges();
// Now update the RaisedPetData with the dragon id
raisedPetRequest.RaisedPetData.RaisedPetID = dragon.Id;
dragon.RaisedPetData = XmlUtil.SerializeXml(raisedPetRequest.RaisedPetData);
ctx.Dragons.Update(dragon);
ctx.SaveChanges();
return Ok(new CreatePetResponse {
RaisedPetData = raisedPetRequest.RaisedPetData
});
}
[HttpPost]
[Produces("application/xml")]
[Route("v3/ContentWebService.asmx/SetRaisedPet")]
public IActionResult SetRaisedPet([FromForm] string apiToken, [FromForm] string request) {
Viking? viking = ctx.Sessions.FirstOrDefault(e => e.ApiToken == apiToken)?.Viking;
if (viking is null) {
// TODO: result for invalid session
return Ok();
}
RaisedPetRequest raisedPetRequest = XmlUtil.DeserializeXml<RaisedPetRequest>(request);
// Find the dragon
Dragon? dragon = viking.Dragons.FirstOrDefault(e => e.Id == raisedPetRequest.RaisedPetData.RaisedPetID);
if (dragon is null) {
return Ok(new SetRaisedPetResponse {
RaisedPetSetResult = RaisedPetSetResult.Invalid
});
}
dragon.RaisedPetData = XmlUtil.SerializeXml(raisedPetRequest.RaisedPetData);
ctx.SaveChanges();
return Ok(new SetRaisedPetResponse {
RaisedPetSetResult = RaisedPetSetResult.Success
});
}
[HttpPost]
[Produces("application/xml")]
[Route("ContentWebService.asmx/SetSelectedPet")]
public IActionResult SetSelectedPet([FromForm] string apiToken, [FromForm] int raisedPetID) {
Viking? viking = ctx.Sessions.FirstOrDefault(e => e.ApiToken == apiToken)?.Viking;
if (viking is null) {
// TODO: result for invalid session
return Ok();
}
// Find the dragon
Dragon? dragon = viking.Dragons.FirstOrDefault(e => e.Id == raisedPetID);
if (dragon is null) {
return Ok(new SetRaisedPetResponse {
RaisedPetSetResult = RaisedPetSetResult.Invalid
});
}
// Set the dragon as selected
RaisedPetData dragonData = XmlUtil.DeserializeXml<RaisedPetData>(dragon.RaisedPetData);
dragonData.IsSelected = true;
dragon.RaisedPetData = XmlUtil.SerializeXml(dragonData);
ctx.SaveChanges();
// TODO: make all other dragons unselected
return Ok(new SetRaisedPetResponse {
RaisedPetSetResult = RaisedPetSetResult.Success
});
}
[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\" />");
[Route("ContentWebService.asmx/GetSelectedRaisedPet")]
public RaisedPetData[]? GetAllActivePetsByuserId([FromForm] string apiToken, [FromForm] string userId, [FromForm] bool active, [FromForm] bool isActive) {
Viking? viking = ctx.Sessions.FirstOrDefault(e => e.ApiToken == apiToken)?.Viking;
if (viking is null) {
return null;
}
// GetAllActivePetsByuserId uses active, and GetSelectedRaisedPet uses active, so OR them together
bool isActiveSet = active || isActive;
RaisedPetData[] dragons = viking.Dragons
.Where(d => d.RaisedPetData is not null)
.Select(d => XmlUtil.DeserializeXml<RaisedPetData>(d.RaisedPetData))
.ToArray();
if (dragons.Length == 0) {
return null;
}
return dragons;
}
[HttpPost]
[Produces("application/xml")]
[Route("ContentWebService.asmx/SetImage")]
public bool SetImage([FromForm] string apiToken, [FromForm] string ImageType, [FromForm] int ImageSlot, [FromForm] string contentXML, [FromForm] string imageFile) {
Viking? viking = ctx.Sessions.FirstOrDefault(e => e.ApiToken == apiToken)?.Viking;
if (viking is null || viking.Dragons is null) {
return false;
}
// TODO: the other properties of contentXML
ImageData data = XmlUtil.DeserializeXml<ImageData>(contentXML);
bool newImage = false;
Image? image = viking.Images.FirstOrDefault(e => e.ImageType == ImageType && e.ImageSlot == ImageSlot);
if (image is null) {
image = new Image {
ImageType = ImageType,
ImageSlot = ImageSlot,
Viking = viking,
};
}
// Save the image in the db
image.ImageData = imageFile;
image.TemplateName = data.TemplateName;
if (newImage) {
ctx.Images.Add(image);
} else {
ctx.Images.Update(image);
}
ctx.SaveChanges();
return true;
}
[HttpPost]
[Produces("application/xml")]
[Route("ContentWebService.asmx/GetImage")]
public ImageData? GetImage([FromForm] string apiToken, [FromForm] string ImageType, [FromForm] int ImageSlot) {
Viking? viking = ctx.Sessions.FirstOrDefault(e => e.ApiToken == apiToken)?.Viking;
if (viking is null || viking.Images is null) {
return null;
}
Image? image = viking.Images.FirstOrDefault(e => e.ImageType == ImageType && e.ImageSlot == ImageSlot);
if (image is null) {
return null;
}
// TODO: test this
return new ImageData {
ImageURL = image.ImageData,
TemplateName = image.TemplateName,
};
}
[HttpPost]

View File

@ -4,6 +4,8 @@ namespace sodoff.Model;
public class DBContext : DbContext {
public DbSet<User> Users { get; set; } = null!;
public DbSet<Viking> Vikings { get; set; } = null!;
public DbSet<Dragon> Dragons { get; set; } = null!;
public DbSet<Image> Images { get; set; } = null!;
public DbSet<Session> Sessions { get; set; } = null!;
public DbSet<Pair> Pairs { get; set; } = null!;
public DbSet<PairData> PairData { get; set; } = null!;
@ -39,6 +41,20 @@ public class DBContext : DbContext {
builder.Entity<User>().HasMany(u => u.Vikings)
.WithOne(e => e.User);
builder.Entity<Dragon>().HasOne(s => s.Viking)
.WithMany(e => e.Dragons)
.HasForeignKey(e => e.VikingId);
builder.Entity<Viking>().HasMany(u => u.Dragons)
.WithOne(e => e.Viking);
builder.Entity<Image>().HasOne(s => s.Viking)
.WithMany(e => e.Images)
.HasForeignKey(e => e.VikingId);
builder.Entity<Viking>().HasMany(u => u.Images)
.WithOne(e => e.Viking);
builder.Entity<PairData>()
.HasKey(e => e.Id);

20
src/Model/Dragon.cs Normal file
View File

@ -0,0 +1,20 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace sodoff.Model;
public class Dragon {
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Required]
public string EntityId { get; set; } = null!;
[Required]
public string VikingId { get; set; } = null!;
public string? RaisedPetData { get; set; }
public virtual Viking Viking { get; set; } = null!;
}

22
src/Model/Image.cs Normal file
View File

@ -0,0 +1,22 @@
using System.ComponentModel.DataAnnotations;
using Microsoft.EntityFrameworkCore;
namespace sodoff.Model;
[PrimaryKey(nameof(ImageType), nameof(ImageSlot), nameof(VikingId))]
public class Image {
[Required]
public string ImageType { get; set; } = null!;
[Required]
public int ImageSlot { get; set; }
[Required]
public string VikingId { get; set; } = null!;
public string? ImageData { get; set; }
public string? TemplateName { get; set; }
public virtual Viking Viking { get; set; } = null!;
}

View File

@ -14,6 +14,7 @@ public class Viking {
public string? AvatarSerialized { get; set; }
public virtual ICollection<Session> Sessions { get; set; } = null!;
public virtual User User { get; set; } = null!;
public virtual ICollection<Dragon> Dragons { get; set; } = null!;
public virtual ICollection<Image> Images { get; set; } = null!;
}

View File

@ -0,0 +1,29 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "CIRT", Namespace = "")]
[Serializable]
public class CommonInventoryRequest
{
[XmlElement(ElementName = "uipid")]
public int? UserItemPositionID { get; set; }
[XmlElement(ElementName = "u")]
public int? Uses { get; set; }
[XmlElement(ElementName = "uia", IsNullable = true)]
public PairData UserItemAttributes { get; set; }
[XmlElement(ElementName = "im", IsNullable = true)]
public int? InventoryMax { get; set; }
[XmlElement(ElementName = "iid")]
public int? ItemID;
[XmlElement(ElementName = "cid")]
public int? CommonInventoryID;
[XmlElement(ElementName = "q")]
public int Quantity;
}

View File

@ -0,0 +1,20 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "CIRS", Namespace = "")]
[Serializable]
public class CommonInventoryResponse
{
[XmlElement(ElementName = "pir", IsNullable = true)]
public List<PrizeItemResponse> PrizeItems { get; set; }
[XmlElement(ElementName = "s")]
public bool Success;
[XmlElement(ElementName = "cids")]
public CommonInventoryResponseItem[] CommonInventoryIDs;
[XmlElement(ElementName = "ugc", IsNullable = true)]
public UserGameCurrency UserGameCurrency;
}

View File

@ -0,0 +1,17 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "CIRI", Namespace = "")]
[Serializable]
public class CommonInventoryResponseItem
{
[XmlElement(ElementName = "iid")]
public int ItemID;
[XmlElement(ElementName = "cid")]
public int CommonInventoryID;
[XmlElement(ElementName = "qty")]
public int Quantity;
}

View File

@ -0,0 +1,14 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "CPR", Namespace = "")]
[Serializable]
public class CreatePetResponse
{
[XmlElement(ElementName = "rpd")]
public RaisedPetData RaisedPetData { get; set; }
[XmlElement(ElementName = "cir")]
public CommonInventoryResponse UserCommonInventoryResponse { get; set; }
}

36
src/Schema/DataType.cs Normal file
View File

@ -0,0 +1,36 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[Flags]
public enum DataType
{
[XmlEnum("1")]
BOOL = 1,
[XmlEnum("2")]
BYTE = 2,
[XmlEnum("3")]
CHAR = 3,
[XmlEnum("4")]
DECIMAL = 4,
[XmlEnum("5")]
DOUBLE = 5,
[XmlEnum("6")]
FLOAT = 6,
[XmlEnum("7")]
INT = 7,
[XmlEnum("8")]
LONG = 8,
[XmlEnum("9")]
SBYTE = 9,
[XmlEnum("10")]
SHORT = 10,
[XmlEnum("11")]
STRING = 11,
[XmlEnum("12")]
UINT = 12,
[XmlEnum("13")]
ULONG = 13,
[XmlEnum("14")]
USHORT = 14
}

29
src/Schema/ImageData.cs Normal file
View File

@ -0,0 +1,29 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "ImageData", Namespace = "", IsNullable = true)]
[Serializable]
public class ImageData {
[XmlElement(ElementName = "ImageURL")]
public string ImageURL;
[XmlElement(ElementName = "TemplateName")]
public string TemplateName;
[XmlElement(ElementName = "SubType", IsNullable = true)]
public string SubType;
[XmlElement(ElementName = "PhotoFrame", IsNullable = true)]
public string PhotoFrame;
[XmlElement(ElementName = "PhotoFrameMask", IsNullable = true)]
public string PhotoFrameMask;
[XmlElement(ElementName = "Border", IsNullable = true)]
public string Border;
[XmlElement(ElementName = "Decal")]
public ImageDataDecal[] Decal;
}

View File

@ -0,0 +1,20 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "ImageDataDecal", Namespace = "")]
[Serializable]
public class ImageDataDecal
{
[XmlElement(ElementName = "Name")]
public string Name;
[XmlElement(ElementName = "Position")]
public ImageDataDecalPosition Position;
[XmlElement(ElementName = "Width")]
public int Width;
[XmlElement(ElementName = "Height")]
public int Height;
}

View File

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

View File

@ -0,0 +1,17 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "pir", Namespace = "")]
[Serializable]
public class PrizeItemResponse
{
[XmlElement(ElementName = "i")]
public int ItemID { get; set; }
[XmlElement(ElementName = "pi")]
public int PrizeItemID { get; set; }
[XmlElement(ElementName = "pis", IsNullable = true)]
public List<ItemData> MysteryPrizeItems { get; set; }
}

View File

@ -0,0 +1,23 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "RPAC", Namespace = "")]
[Serializable]
public class RaisedPetAccessory
{
[XmlElement(ElementName = "tp")]
public string Type;
[XmlElement(ElementName = "g")]
public string Geometry;
[XmlElement(ElementName = "t")]
public string Texture;
[XmlElement(ElementName = "uiid", IsNullable = true)]
public int? UserInventoryCommonID;
[XmlElement(ElementName = "uid", IsNullable = true)]
public UserItemData UserItemData;
}

View File

@ -0,0 +1,17 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "RPAT", Namespace = "")]
[Serializable]
public class RaisedPetAttribute
{
[XmlElement(ElementName = "k")]
public string Key;
[XmlElement(ElementName = "v")]
public string Value;
[XmlElement(ElementName = "dt")]
public DataType Type;
}

View File

@ -0,0 +1,20 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "RPC", Namespace = "")]
[Serializable]
public class RaisedPetColor
{
[XmlElement(ElementName = "o")]
public int Order;
[XmlElement(ElementName = "r")]
public float Red;
[XmlElement(ElementName = "g")]
public float Green;
[XmlElement(ElementName = "b")]
public float Blue;
}

View File

@ -0,0 +1,71 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "RPD", Namespace = "")]
[Serializable]
public class RaisedPetData
{
[XmlElement(ElementName = "ispetcreated")]
public bool IsPetCreated { get; set; }
[XmlElement(ElementName = "validationmessage")]
public string ValidationMessage { get; set; }
[XmlElement(ElementName = "id")]
public int RaisedPetID;
[XmlElement(ElementName = "eid", IsNullable = true)]
public Guid? EntityID;
[XmlElement(ElementName = "uid")]
public Guid UserID;
[XmlElement(ElementName = "n")]
public string Name;
[XmlElement(ElementName = "ptid")]
public int PetTypeID;
[XmlElement(ElementName = "gs")]
public RaisedPetGrowthState GrowthState;
[XmlElement(ElementName = "ip", IsNullable = true)]
public int? ImagePosition;
[XmlElement(ElementName = "g")]
public string Geometry;
[XmlElement(ElementName = "t")]
public string Texture;
[XmlElement(ElementName = "gd")]
public Gender Gender;
[XmlElement(ElementName = "ac")]
public RaisedPetAccessory[] Accessories;
[XmlElement(ElementName = "at")]
public RaisedPetAttribute[] Attributes;
[XmlElement(ElementName = "c")]
public RaisedPetColor[] Colors;
[XmlElement(ElementName = "sk")]
public RaisedPetSkill[] Skills;
[XmlElement(ElementName = "st")]
public RaisedPetState[] States;
[XmlElement(ElementName = "is")]
public bool IsSelected;
[XmlElement(ElementName = "ir")]
public bool IsReleased;
[XmlElement(ElementName = "cdt")]
public DateTime CreateDate;
[XmlElement(ElementName = "updt")]
public DateTime UpdateDate;
}

View File

@ -0,0 +1,20 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "RPGS", Namespace = "")]
[Serializable]
public class RaisedPetGrowthState
{
[XmlElement(ElementName = "id")]
public int GrowthStateID;
[XmlElement(ElementName = "n")]
public string Name;
[XmlElement(ElementName = "ptid")]
public int PetTypeID;
[XmlElement(ElementName = "o")]
public int Order;
}

View File

@ -0,0 +1,32 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "RPR", Namespace = "")]
[Serializable]
public class RaisedPetRequest
{
[XmlElement(ElementName = "ptid")]
public int PetTypeID { get; set; }
[XmlElement(ElementName = "uid")]
public Guid? UserID { get; set; }
[XmlElement(ElementName = "SASP")]
public bool? SetAsSelectedPet { get; set; }
[XmlElement(ElementName = "USOP")]
public bool? UnSelectOtherPets { get; set; }
[XmlElement(ElementName = "pgid")]
public int? ProductGroupID { get; set; }
[XmlElement(ElementName = "cid")]
public int? ContainerId { get; set; }
[XmlElement(ElementName = "cir")]
public CommonInventoryRequest[] CommonInventoryRequests { get; set; }
[XmlElement(ElementName = "rpd")]
public RaisedPetData RaisedPetData { get; set; }
}

View File

@ -0,0 +1,18 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
public enum RaisedPetSetResult
{
[XmlEnum("1")]
Success = 1,
[XmlEnum("2")]
Failure,
[XmlEnum("3")]
Invalid,
[XmlEnum("4")]
InvalidPetName
}

View File

@ -0,0 +1,17 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "RPSK", Namespace = "")]
[Serializable]
public class RaisedPetSkill
{
[XmlElement(ElementName = "k")]
public string Key;
[XmlElement(ElementName = "v")]
public float Value;
[XmlElement(ElementName = "ud")]
public DateTime UpdateDate;
}

View File

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

View File

@ -0,0 +1,17 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "SetRaisedPetResponse", Namespace = "")]
[Serializable]
public class SetRaisedPetResponse
{
[XmlElement(ElementName = "ErrorMessage")]
public string ErrorMessage { get; set; }
[XmlElement(ElementName = "RaisedPetSetResult")]
public RaisedPetSetResult RaisedPetSetResult { get; set; }
[XmlElement(ElementName = "cir")]
public CommonInventoryResponse UserCommonInventoryResponse { get; set; }
}

View File

@ -0,0 +1,20 @@
using System.Xml.Serialization;
namespace sodoff.Schema;
[XmlRoot(ElementName = "UserGameCurrency", Namespace = "")]
[Serializable]
public class UserGameCurrency
{
[XmlElement(ElementName = "id")]
public int? UserGameCurrencyID;
[XmlElement(ElementName = "uid")]
public Guid? UserID;
[XmlElement(ElementName = "gc")]
public int? GameCurrency;
[XmlElement(ElementName = "cc")]
public int? CashCurrency;
}