diff --git a/mitm-redirect.py b/mitm-redirect.py index 691a511..3beaf06 100644 --- a/mitm-redirect.py +++ b/mitm-redirect.py @@ -4,6 +4,7 @@ import mitmproxy.http methods = [ 'GetRules', 'LoginParent', + 'AuthenticateUser', 'RegisterParent', 'GetSubscriptionInfo', 'GetUserInfoByApiToken', diff --git a/src/Attributes/DecryptRequest.cs b/src/Attributes/DecryptRequest.cs index 46b4d7a..fe10355 100644 --- a/src/Attributes/DecryptRequest.cs +++ b/src/Attributes/DecryptRequest.cs @@ -5,6 +5,7 @@ using sodoff.Util; namespace sodoff.Attributes; +[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] public class DecryptRequest : Attribute, IAsyncActionFilter { const string key = "56BB211B-CF06-48E1-9C1D-E40B5173D759"; diff --git a/src/Controllers/Common/AuthenticationController.cs b/src/Controllers/Common/AuthenticationController.cs index fabd1eb..8407287 100644 --- a/src/Controllers/Common/AuthenticationController.cs +++ b/src/Controllers/Common/AuthenticationController.cs @@ -64,6 +64,24 @@ public class AuthenticationController : Controller { return Ok(response); } + [HttpPost] + [Produces("application/xml")] + [Route("v3/AuthenticationWebService.asmx/AuthenticateUser")] + [DecryptRequest("username")] + [DecryptRequest("password")] + public bool AuthenticateUser() { + String username = Request.Form["username"]; + String password = Request.Form["password"]; + + // Authenticate the user + User? user = ctx.Users.FirstOrDefault(e => e.Username == username); + if (user is null || new PasswordHasher().VerifyHashedPassword(null, user.Password, password) != PasswordVerificationResult.Success) { + return false; + } + + return true; + } + [HttpPost] [Produces("application/xml")] [Route("AuthenticationWebService.asmx/GetUserInfoByApiToken")] diff --git a/src/Controllers/Common/ContentController.cs b/src/Controllers/Common/ContentController.cs index bdd436d..fdc66f9 100644 --- a/src/Controllers/Common/ContentController.cs +++ b/src/Controllers/Common/ContentController.cs @@ -271,6 +271,8 @@ public class ContentController : Controller { ctx.Dragons.Add(dragon); ctx.SaveChanges(); + // TODO: handle CommonInventoryRequests here too + return Ok(new CreatePetResponse { RaisedPetData = GetRaisedPetDataFromDragon(dragon) }); @@ -296,10 +298,12 @@ public class ContentController : Controller { }); } - dragon.RaisedPetData = XmlUtil.SerializeXml(raisedPetRequest.RaisedPetData); + dragon.RaisedPetData = XmlUtil.SerializeXml(UpdateDragon(dragon, raisedPetRequest.RaisedPetData)); ctx.Update(dragon); ctx.SaveChanges(); + // TODO: handle CommonInventoryRequests here too + return Ok(new SetRaisedPetResponse { RaisedPetSetResult = RaisedPetSetResult.Success }); @@ -508,6 +512,48 @@ public class ContentController : Controller { return data; } + // Needs to merge newDragonData into dragonData + private RaisedPetData UpdateDragon (Dragon dragon, RaisedPetData newDragonData) { + RaisedPetData dragonData = XmlUtil.DeserializeXml(dragon.RaisedPetData); + + // The simple attributes + dragonData.IsPetCreated = newDragonData.IsPetCreated; + if (newDragonData.ValidationMessage is not null) dragonData.ValidationMessage = newDragonData.ValidationMessage; + if (newDragonData.EntityID is not null) dragonData.EntityID = newDragonData.EntityID; + if (newDragonData.Name is not null) dragonData.Name = newDragonData.Name; + dragonData.PetTypeID = newDragonData.PetTypeID; + if (newDragonData.GrowthState is not null) dragonData.GrowthState = newDragonData.GrowthState; + if (newDragonData.ImagePosition is not null) dragonData.ImagePosition = newDragonData.ImagePosition; + if (newDragonData.Geometry is not null) dragonData.Geometry = newDragonData.Geometry; + if (newDragonData.Texture is not null) dragonData.Texture = newDragonData.Texture; + dragonData.Gender = newDragonData.Gender; + if (newDragonData.Accessories is not null) dragonData.Accessories = newDragonData.Accessories; + if (newDragonData.Colors is not null) dragonData.Colors = newDragonData.Colors; + if (newDragonData.Skills is not null) dragonData.Skills = newDragonData.Skills; + if (newDragonData.States is not null) dragonData.States = newDragonData.States; + + dragonData.IsSelected = newDragonData.IsSelected; + dragonData.IsReleased = newDragonData.IsReleased; + dragonData.UpdateDate = newDragonData.UpdateDate; + + // Attributes is special - the entire list isn't re-sent, so we need to manually update each + if (dragonData.Attributes is null) dragonData.Attributes = new RaisedPetAttribute[] { }; + if (newDragonData.Attributes is not null) { + foreach (RaisedPetAttribute newAttribute in newDragonData.Attributes) { + RaisedPetAttribute? attribute = dragonData.Attributes.FirstOrDefault(a => a.Key == newAttribute.Key); + if (attribute is null) { + dragonData.Attributes.Append(newAttribute); + } + else { + attribute.Value = newAttribute.Value; + attribute.Type = newAttribute.Type; + } + } + } + + return dragonData; + } + 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) {