mirror of
https://github.com/SoDOff-Project/sodoff.git
synced 2025-10-11 08:18:49 -07:00
SoD bug fixes
- fish trap on the farm now gives a reward - added support for revard via achievements in RoomService - added achievements for fish trap rewards - fixed DuplicateUserName message on SoD 1.13 - not encrypted responses with correct schema in V3/RegistrationWebService.asmx/RegisterChild - fixed putting racing sheep into farm - implemented /ContentWebService.asmx/RedeemItems thanks to @ABrokenTV for debug these issues
This commit is contained in:
parent
59c722fe65
commit
8d8b9a4566
@ -1185,6 +1185,42 @@ public class ContentController : Controller {
|
|||||||
return Ok(new BuddyList { Buddy = new Buddy[0] });
|
return Ok(new BuddyList { Buddy = new Buddy[0] });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Produces("application/xml")]
|
||||||
|
[Route("/ContentWebService.asmx/RedeemItems")]
|
||||||
|
[VikingSession]
|
||||||
|
public IActionResult RedeemItems(Viking viking, [FromForm] string request) {
|
||||||
|
var req = XmlUtil.DeserializeXml<RedeemRequest>(request);
|
||||||
|
Dictionary<int, int> inventoryItemsToAdd = new();
|
||||||
|
|
||||||
|
// resolve items in the bundle
|
||||||
|
ItemData bundleItem = itemService.GetItem(req.ItemID);
|
||||||
|
foreach (var reward in bundleItem.Relationship.Where(e => e.Type == "Bundle")) {
|
||||||
|
int quantity = itemService.GetItemQuantity(reward, 1);
|
||||||
|
inventoryItemsToAdd.TryAdd(reward.ItemId, 0);
|
||||||
|
inventoryItemsToAdd[reward.ItemId] += quantity;
|
||||||
|
}
|
||||||
|
|
||||||
|
var addedItems = inventoryService.AddItemsToInventoryBulk(viking, inventoryItemsToAdd);
|
||||||
|
|
||||||
|
// build response
|
||||||
|
List<CommonInventoryResponseItem> items = new List<CommonInventoryResponseItem>();
|
||||||
|
foreach (var i in inventoryItemsToAdd) {
|
||||||
|
items.AddRange(Enumerable.Repeat(
|
||||||
|
new CommonInventoryResponseItem {
|
||||||
|
CommonInventoryID = addedItems.ContainsKey(i.Key) ? addedItems[i.Key] : 0, // return inventory id if this item was added to the DB
|
||||||
|
ItemID = i.Key,
|
||||||
|
Quantity = 0
|
||||||
|
}, i.Value));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok(new CommonInventoryResponse{
|
||||||
|
Success = true,
|
||||||
|
CommonInventoryIDs = items.ToArray(),
|
||||||
|
UserGameCurrency = achievementService.GetUserCurrency(viking)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[Produces("application/xml")]
|
[Produces("application/xml")]
|
||||||
[Route("/ContentWebService.asmx/RedeemMysteryBoxItems")]
|
[Route("/ContentWebService.asmx/RedeemMysteryBoxItems")]
|
||||||
|
@ -100,7 +100,6 @@ public class RegistrationController : Controller {
|
|||||||
|
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[Produces("application/xml")]
|
[Produces("application/xml")]
|
||||||
[Route("V3/RegistrationWebService.asmx/RegisterChild")] // used by Magic & Mythies
|
|
||||||
[Route("V4/RegistrationWebService.asmx/RegisterChild")]
|
[Route("V4/RegistrationWebService.asmx/RegisterChild")]
|
||||||
[DecryptRequest("childRegistrationData")]
|
[DecryptRequest("childRegistrationData")]
|
||||||
[EncryptResponse]
|
[EncryptResponse]
|
||||||
@ -131,6 +130,34 @@ public class RegistrationController : Controller {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Produces("application/xml")]
|
||||||
|
[Route("V3/RegistrationWebService.asmx/RegisterChild")] // used by SoD 1.13 and Magic & Mythies
|
||||||
|
[DecryptRequest("childRegistrationData")]
|
||||||
|
public IActionResult RegisterChildV3([FromForm] Guid parentApiToken, [FromForm] string apiKey) {
|
||||||
|
User? user = ctx.Sessions.FirstOrDefault(e => e.ApiToken == parentApiToken)?.User;
|
||||||
|
if (user is null) {
|
||||||
|
return Ok(new RegistrationResult{
|
||||||
|
Status = MembershipUserStatus.InvalidApiToken
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if name populated
|
||||||
|
ChildRegistrationData data = XmlUtil.DeserializeXml<ChildRegistrationData>(Request.Form["childRegistrationData"]);
|
||||||
|
if (String.IsNullOrWhiteSpace(data.ChildName)) {
|
||||||
|
return Ok(MembershipUserStatus.ValidationError);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if viking exists
|
||||||
|
if (ctx.Vikings.Count(e => e.Name == data.ChildName) > 0) {
|
||||||
|
return Ok(MembershipUserStatus.DuplicateUserName);
|
||||||
|
}
|
||||||
|
|
||||||
|
Viking v = CreateViking(user, data, ClientVersion.GetVersion(apiKey));
|
||||||
|
|
||||||
|
return Ok(MembershipUserStatus.Success);
|
||||||
|
}
|
||||||
|
|
||||||
private Viking CreateViking(User user, ChildRegistrationData data, uint gameVersion) {
|
private Viking CreateViking(User user, ChildRegistrationData data, uint gameVersion) {
|
||||||
List<InventoryItem> items = new();
|
List<InventoryItem> items = new();
|
||||||
if (gameVersion >= ClientVersion.Min_SoD) {
|
if (gameVersion >= ClientVersion.Min_SoD) {
|
||||||
|
@ -3029,6 +3029,164 @@
|
|||||||
<!-- mission reward achievements (`<AID>` tag in `missions.xml` file) -->
|
<!-- mission reward achievements (`<AID>` tag in `missions.xml` file) -->
|
||||||
<!-- do NOT add missions reward achievements to this file to avoid duplication of rewards -->
|
<!-- do NOT add missions reward achievements to this file to avoid duplication of rewards -->
|
||||||
|
|
||||||
|
<!-- fish trap rewards (probability of each 10%), do not correspond to the original ones, max 3 reward's item per achievements due to client limitation -->
|
||||||
|
<AchievementsIdInfo>
|
||||||
|
<AID>201388</AID>
|
||||||
|
<AR>
|
||||||
|
<p>6</p>
|
||||||
|
<a>3</a>
|
||||||
|
<t>1</t>
|
||||||
|
<r>8</r>
|
||||||
|
<ii>7143</ii><!-- Perch -->
|
||||||
|
</AR>
|
||||||
|
<AR>
|
||||||
|
<p>6</p>
|
||||||
|
<a>2</a>
|
||||||
|
<t>1</t>
|
||||||
|
<r>8</r>
|
||||||
|
<ii>7139</ii><!-- Brown Trout -->
|
||||||
|
</AR>
|
||||||
|
<AR>
|
||||||
|
<p>6</p>
|
||||||
|
<a>1</a>
|
||||||
|
<t>1</t>
|
||||||
|
<r>8</r>
|
||||||
|
<ii>7144</ii><!-- Salmon -->
|
||||||
|
</AR>
|
||||||
|
</AchievementsIdInfo>
|
||||||
|
<AchievementsIdInfo>
|
||||||
|
<AID>201389</AID>
|
||||||
|
<AR>
|
||||||
|
<p>6</p>
|
||||||
|
<a>4</a>
|
||||||
|
<t>1</t>
|
||||||
|
<r>8</r>
|
||||||
|
<ii>7143</ii><!-- Perch -->
|
||||||
|
</AR>
|
||||||
|
</AchievementsIdInfo>
|
||||||
|
<AchievementsIdInfo>
|
||||||
|
<AID>201390</AID>
|
||||||
|
<AR>
|
||||||
|
<p>6</p>
|
||||||
|
<a>2</a>
|
||||||
|
<t>1</t>
|
||||||
|
<r>8</r>
|
||||||
|
<ii>7143</ii><!-- Perch -->
|
||||||
|
</AR>
|
||||||
|
<AR>
|
||||||
|
<p>6</p>
|
||||||
|
<a>1</a>
|
||||||
|
<t>1</t>
|
||||||
|
<r>8</r>
|
||||||
|
<ii>7139</ii><!-- Brown Trout -->
|
||||||
|
</AR>
|
||||||
|
</AchievementsIdInfo>
|
||||||
|
<AchievementsIdInfo>
|
||||||
|
<AID>201391</AID>
|
||||||
|
<AR>
|
||||||
|
<p>6</p>
|
||||||
|
<a>3</a>
|
||||||
|
<t>1</t>
|
||||||
|
<r>8</r>
|
||||||
|
<ii>7140</ii><!-- Eel -->
|
||||||
|
</AR>
|
||||||
|
</AchievementsIdInfo>
|
||||||
|
<AchievementsIdInfo>
|
||||||
|
<AID>201392</AID>
|
||||||
|
<AR>
|
||||||
|
<p>6</p>
|
||||||
|
<a>1</a>
|
||||||
|
<t>1</t>
|
||||||
|
<r>8</r>
|
||||||
|
<ii>7140</ii><!-- Eel -->
|
||||||
|
</AR>
|
||||||
|
<AR>
|
||||||
|
<p>6</p>
|
||||||
|
<a>3</a>
|
||||||
|
<t>1</t>
|
||||||
|
<r>8</r>
|
||||||
|
<ii>7144</ii><!-- Salmon -->
|
||||||
|
</AR>
|
||||||
|
</AchievementsIdInfo>
|
||||||
|
<AchievementsIdInfo>
|
||||||
|
<AID>201393</AID>
|
||||||
|
<AR>
|
||||||
|
<p>6</p>
|
||||||
|
<a>5</a>
|
||||||
|
<t>1</t>
|
||||||
|
<r>8</r>
|
||||||
|
<ii>7143</ii><!-- Perch -->
|
||||||
|
</AR>
|
||||||
|
<AR>
|
||||||
|
<p>6</p>
|
||||||
|
<a>1</a>
|
||||||
|
<t>1</t>
|
||||||
|
<r>8</r>
|
||||||
|
<ii>7140</ii><!-- Eel -->
|
||||||
|
</AR>
|
||||||
|
</AchievementsIdInfo>
|
||||||
|
<AchievementsIdInfo>
|
||||||
|
<AID>201394</AID>
|
||||||
|
<AR>
|
||||||
|
<p>6</p>
|
||||||
|
<a>1</a>
|
||||||
|
<t>1</t>
|
||||||
|
<r>8</r>
|
||||||
|
<ii>7143</ii><!-- Perch -->
|
||||||
|
</AR>
|
||||||
|
<AR>
|
||||||
|
<p>6</p>
|
||||||
|
<a>2</a>
|
||||||
|
<t>1</t>
|
||||||
|
<r>8</r>
|
||||||
|
<ii>7139</ii><!-- Brown Trout -->
|
||||||
|
</AR>
|
||||||
|
<AR>
|
||||||
|
<p>6</p>
|
||||||
|
<a>2</a>
|
||||||
|
<t>1</t>
|
||||||
|
<r>8</r>
|
||||||
|
<ii>7144</ii><!-- Salmon -->
|
||||||
|
</AR>
|
||||||
|
</AchievementsIdInfo>
|
||||||
|
<AchievementsIdInfo>
|
||||||
|
<AID>201395</AID>
|
||||||
|
<AR>
|
||||||
|
<p>6</p>
|
||||||
|
<a>5</a>
|
||||||
|
<t>1</t>
|
||||||
|
<r>8</r>
|
||||||
|
<ii>7139</ii><!-- Brown Trout -->
|
||||||
|
</AR>
|
||||||
|
</AchievementsIdInfo>
|
||||||
|
<AchievementsIdInfo>
|
||||||
|
<AID>201396</AID>
|
||||||
|
<AR>
|
||||||
|
<p>6</p>
|
||||||
|
<a>5</a>
|
||||||
|
<t>1</t>
|
||||||
|
<r>8</r>
|
||||||
|
<ii>7144</ii><!-- Salmon -->
|
||||||
|
</AR>
|
||||||
|
</AchievementsIdInfo>
|
||||||
|
<AchievementsIdInfo>
|
||||||
|
<AID>201397</AID>
|
||||||
|
<AR>
|
||||||
|
<p>6</p>
|
||||||
|
<a>3</a>
|
||||||
|
<t>1</t>
|
||||||
|
<r>8</r>
|
||||||
|
<ii>7139</ii><!-- Brown Trout -->
|
||||||
|
</AR>
|
||||||
|
<AR>
|
||||||
|
<p>6</p>
|
||||||
|
<a>2</a>
|
||||||
|
<t>1</t>
|
||||||
|
<r>8</r>
|
||||||
|
<ii>7144</ii><!-- Salmon -->
|
||||||
|
</AR>
|
||||||
|
</AchievementsIdInfo>
|
||||||
|
|
||||||
<!-- stable missions reward achievements -->
|
<!-- stable missions reward achievements -->
|
||||||
<AchievementsIdInfo>
|
<AchievementsIdInfo>
|
||||||
<AID>201323</AID>
|
<AID>201323</AID>
|
||||||
|
11
src/Schema/AchievementCompletion.cs
Normal file
11
src/Schema/AchievementCompletion.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
using System.Xml.Serialization;
|
||||||
|
|
||||||
|
namespace sodoff.Schema;
|
||||||
|
|
||||||
|
[XmlRoot(ElementName = "AchievementCompletion", Namespace = "")]
|
||||||
|
[Serializable]
|
||||||
|
public class AchievementCompletion
|
||||||
|
{
|
||||||
|
[XmlElement(ElementName = "AchievementID")]
|
||||||
|
public int AchievementID;
|
||||||
|
}
|
@ -12,4 +12,7 @@ public class CompletionAction {
|
|||||||
|
|
||||||
[XmlElement(ElementName = "Transition")]
|
[XmlElement(ElementName = "Transition")]
|
||||||
public StateTransition Transition;
|
public StateTransition Transition;
|
||||||
|
|
||||||
|
[XmlElement(ElementName = "AchievementCompletion", IsNullable = true)]
|
||||||
|
public AchievementCompletion[] AchievementCompletion;
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ public class RoomService {
|
|||||||
|
|
||||||
private ItemService itemService;
|
private ItemService itemService;
|
||||||
private AchievementService achievementService;
|
private AchievementService achievementService;
|
||||||
|
private Random random = new Random();
|
||||||
|
|
||||||
public RoomService(DBContext ctx, ItemService itemService, AchievementService achievementService) {
|
public RoomService(DBContext ctx, ItemService itemService, AchievementService achievementService) {
|
||||||
this.ctx = ctx;
|
this.ctx = ctx;
|
||||||
@ -125,8 +126,9 @@ public class RoomService {
|
|||||||
UserItemPosition pos = XmlUtil.DeserializeXml<UserItemPosition>(item.RoomItemData);
|
UserItemPosition pos = XmlUtil.DeserializeXml<UserItemPosition>(item.RoomItemData);
|
||||||
|
|
||||||
AchievementReward[]? rewards;
|
AchievementReward[]? rewards;
|
||||||
|
int? achievementID;
|
||||||
List<ItemStateCriteria> consumables;
|
List<ItemStateCriteria> consumables;
|
||||||
int nextStateID = GetNextStateID(pos, speedup, out rewards, out consumables);
|
int nextStateID = GetNextStateID(pos, speedup, out rewards, out achievementID, out consumables);
|
||||||
|
|
||||||
foreach (var consumable in consumables) {
|
foreach (var consumable in consumables) {
|
||||||
ItemStateCriteriaConsumable c = (ItemStateCriteriaConsumable)consumable;
|
ItemStateCriteriaConsumable c = (ItemStateCriteriaConsumable)consumable;
|
||||||
@ -138,6 +140,13 @@ public class RoomService {
|
|||||||
if (rewards != null) {
|
if (rewards != null) {
|
||||||
response.Rewards = achievementService.ApplyAchievementRewards(item.Room.Viking, rewards);
|
response.Rewards = achievementService.ApplyAchievementRewards(item.Room.Viking, rewards);
|
||||||
}
|
}
|
||||||
|
if (achievementID != null) {
|
||||||
|
var newrewards = achievementService.ApplyAchievementRewardsByID(item.Room.Viking, (int)achievementID);
|
||||||
|
if (response.Rewards is null)
|
||||||
|
response.Rewards = newrewards;
|
||||||
|
else
|
||||||
|
response.Rewards = response.Rewards.Concat(newrewards).ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
DateTime stateChange = new DateTime(DateTime.Now.Ticks);
|
DateTime stateChange = new DateTime(DateTime.Now.Ticks);
|
||||||
if (nextStateID == -1) {
|
if (nextStateID == -1) {
|
||||||
@ -164,8 +173,9 @@ public class RoomService {
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int GetNextStateID(UserItemPosition pos, bool speedup, out AchievementReward[]? rewards, out List<ItemStateCriteria> consumables) {
|
private int GetNextStateID(UserItemPosition pos, bool speedup, out AchievementReward[]? rewards, out int? achievementID, out List<ItemStateCriteria> consumables) {
|
||||||
rewards = null;
|
rewards = null;
|
||||||
|
achievementID = null;
|
||||||
consumables = new List<ItemStateCriteria>();
|
consumables = new List<ItemStateCriteria>();
|
||||||
|
|
||||||
if (pos.UserItemState == null)
|
if (pos.UserItemState == null)
|
||||||
@ -175,6 +185,13 @@ public class RoomService {
|
|||||||
rewards = currState.Rewards;
|
rewards = currState.Rewards;
|
||||||
consumables = currState.Rule.Criterias.FindAll(x => x.Type == ItemStateCriteriaType.ConsumableItem);
|
consumables = currState.Rule.Criterias.FindAll(x => x.Type == ItemStateCriteriaType.ConsumableItem);
|
||||||
|
|
||||||
|
// achievementID = currState.AchievementID; // TODO we should do this or not? some items use the same rewards in `currState.Rewards` and achievement definition, but some do not contain only achievementID (but then there is generally no definition for achievement)
|
||||||
|
if (currState.Rule.CompletionAction.AchievementCompletion != null) {
|
||||||
|
achievementID = currState.Rule.CompletionAction.AchievementCompletion[
|
||||||
|
random.Next(0, currState.Rule.CompletionAction.AchievementCompletion.Length)
|
||||||
|
].AchievementID;
|
||||||
|
}
|
||||||
|
|
||||||
if (speedup)
|
if (speedup)
|
||||||
return ((ItemStateCriteriaSpeedUpItem)currState.Rule.Criterias.Find(x => x.Type == ItemStateCriteriaType.SpeedUpItem)!).EndStateID;
|
return ((ItemStateCriteriaSpeedUpItem)currState.Rule.Criterias.Find(x => x.Type == ItemStateCriteriaType.SpeedUpItem)!).EndStateID;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user