Merge pull request #4 from hictooth/hictooth/dragons

dragons and pets
This commit is contained in:
Spirtix 2023-06-22 12:16:19 +02:00 committed by GitHub
commit 2fa769fda8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 842 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,6 +45,14 @@ Then run School of Dragons.
- SetAvatar
- RegisterParent
- RegisterChild
- CreatePet
- SetRaisedPet
- SetSelectedPet
- GetAllActivePetsByuserId
- GetSelectedRaisedPet
- SetImage
- GetImage
- GetImageByUserId
#### Implemented enough (probably)
- GetRules (doesn't return any rules, probably doesn't need to)
@ -64,7 +72,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,47 @@
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',
'GetPetAchievementsByUserID',
'GetDetailedChildList',
'GetStore',
'GetAllRanks',
'GetUserUpcomingMissionState',
'GetUserActiveMissionState',
'GetUserCompletedMissionState',
'SetTaskState',
'CreatePet',
'SetRaisedPet',
'SetSelectedPet',
'GetAllActivePetsByuserId',
'GetSelectedRaisedPet',
'SetImage',
'GetImage',
'GetImageByUserId'
]
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,204 @@ 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),
};
if (raisedPetRequest.SetAsSelectedPet == true) {
viking.SelectedDragon = dragon;
ctx.Update(viking);
}
ctx.Dragons.Add(dragon);
ctx.SaveChanges();
return Ok(new CreatePetResponse {
RaisedPetData = GetRaisedPetDataFromDragon(dragon)
});
}
[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.Update(dragon);
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
viking.SelectedDragon = dragon;
ctx.Update(viking);
ctx.SaveChanges();
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\" />");
public RaisedPetData[]? GetAllActivePetsByuserId([FromForm] string apiToken, [FromForm] string userId, [FromForm] bool active) {
Viking? viking = ctx.Sessions.FirstOrDefault(e => e.ApiToken == apiToken)?.Viking;
if (viking is null) {
return null;
}
RaisedPetData[] dragons = viking.Dragons
.Where(d => d.RaisedPetData is not null)
.Select(GetRaisedPetDataFromDragon)
.ToArray();
if (dragons.Length == 0) {
return null;
}
return dragons;
}
[HttpPost]
[Produces("application/xml")]
[Route("ContentWebService.asmx/GetSelectedRaisedPet")]
public RaisedPetData[]? GetSelectedRaisedPet([FromForm] string apiToken, [FromForm] string userId, [FromForm] bool isActive) {
Viking? viking = ctx.Sessions.FirstOrDefault(e => e.ApiToken == apiToken)?.Viking;
if (viking is null) {
return null;
}
Dragon? dragon = viking.SelectedDragon;
if (dragon is null) {
return null;
}
return new RaisedPetData[] {
GetRaisedPetDataFromDragon(dragon)
};
}
[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,
};
newImage = true;
}
// 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;
}
return GetImageData(viking, ImageType, ImageSlot);
}
[HttpPost]
[Produces("application/xml")]
[Route("ContentWebService.asmx/GetImageByUserId")]
public ImageData? GetImageByUserId([FromForm] string userId, [FromForm] string ImageType, [FromForm] int ImageSlot) {
Viking? viking = ctx.Vikings.FirstOrDefault(e => e.Id == userId);
if (viking is null || viking.Images is null) {
return null;
}
// TODO: should we restrict images to only those the caller owns?
return GetImageData(viking, ImageType, ImageSlot);
}
[HttpPost]
@ -288,4 +482,26 @@ public class ContentController : Controller {
return Ok(new SetTaskStateResult { Success = true, Status = SetTaskStateStatus.TaskCanBeDone });
}
private RaisedPetData GetRaisedPetDataFromDragon (Dragon dragon) {
RaisedPetData data = XmlUtil.DeserializeXml<RaisedPetData>(dragon.RaisedPetData);
data.RaisedPetID = dragon.Id;
data.EntityID = Guid.Parse(dragon.EntityId);
data.IsSelected = dragon.SelectedViking is not null;
return data;
}
private ImageData? GetImageData (Viking viking, String ImageType, int ImageSlot) {
Image? image = viking.Images.FirstOrDefault(e => e.ImageType == ImageType && e.ImageSlot == ImageSlot);
if (image is null) {
return null;
}
string imageUrl = string.Format("{0}://{1}/RawImage/{2}/{3}/{4}", HttpContext.Request.Scheme, HttpContext.Request.Host, viking.Id, ImageType, ImageSlot);
return new ImageData {
ImageURL = imageUrl,
TemplateName = image.TemplateName,
};
}
}

View File

@ -0,0 +1,34 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using sodoff.Attributes;
using sodoff.Model;
using sodoff.Schema;
using sodoff.Services;
using sodoff.Util;
using System;
namespace sodoff.Controllers.Common;
public class ImageController : Controller {
private readonly DBContext ctx;
private KeyValueService keyValueService;
public ImageController(DBContext ctx, KeyValueService keyValueService) {
this.ctx = ctx;
this.keyValueService = keyValueService;
}
// SetImage and GetImage are defined in ContentController
[HttpGet]
[Route("RawImage/{VikingId}/{ImageType}/{ImageSlot}")]
public IActionResult RawImage(String VikingId, String ImageType, int ImageSlot) {
Image? image = ctx.Images.FirstOrDefault(e => e.VikingId == VikingId && e.ImageType == ImageType && e.ImageSlot == ImageSlot);
if (image is null) {
return null;
}
byte[] imageBytes = Convert.FromBase64String(image.ImageData);
var imageStream = new MemoryStream(imageBytes, 0, imageBytes.Length);
return File(imageStream, "image/jpeg");
}
}

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,28 @@ 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<Viking>().HasOne(s => s.SelectedDragon)
.WithOne(e => e.SelectedViking)
.HasForeignKey<Dragon>(e => e.SelectedVikingId);
builder.Entity<Dragon>().HasOne(s => s.SelectedViking)
.WithOne(e => e.SelectedDragon)
.HasForeignKey<Viking>(e => e.SelectedDragonId);
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);

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

@ -0,0 +1,23 @@
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? SelectedVikingId { get; set; }
public string? RaisedPetData { get; set; }
public virtual Viking Viking { get; set; } = null!;
public virtual Viking SelectedViking { 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

@ -13,7 +13,11 @@ public class Viking {
public string? AvatarSerialized { get; set; }
public virtual ICollection<Session> Sessions { get; set; } = null!;
public int? SelectedDragonId { 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!;
public virtual Dragon? SelectedDragon { get; set; }
}

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;
}