diff --git a/README.md b/README.md index 9f3d148..2da701f 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,10 @@

Feels like a distant memory

# WhimsyWorld +![Gitea Last Commit](https://img.shields.io/gitea/last-commit/alterwain/WhimsyWorld?gitea_url=https%3A%2F%2Fgitea.awain.net) +![Jenkins Build](https://img.shields.io/jenkins/build?jobUrl=https%3A%2F%2Fjenkins.awain.net%2Fjob%2FWhimsyWorld&link=https%3A%2F%2Fjenkins.awain.net%2Fjob%2FWhimsyWorld) +![Contact](https://img.shields.io/badge/xmpp-alterwain-red?link=xmpp%3Aalterwain%40awain.net%3Fomemo-sid-687809972%3Dfc938d0c120affd1f011a1f1e53449b8b773ac7c322667f1dca2b2539987b86c) + An unofficial server for semi-famous game Rolypolyland (Shararam). Remake by alterwain. Original by cl0zzzy (also me, but in 2018). ## Caution diff --git a/src/main/java/com/alterdekim/game/component/GameServer.java b/src/main/java/com/alterdekim/game/component/GameServer.java index cce37d2..1c4234c 100644 --- a/src/main/java/com/alterdekim/game/component/GameServer.java +++ b/src/main/java/com/alterdekim/game/component/GameServer.java @@ -345,7 +345,7 @@ public class GameServer { List> l = Stream.concat( bodyParts.stream().map(f -> (Map) f.getValue()).map(f -> Triplet.with(((Number) f.get("Id").getValue()).longValue(), f.get("Color").getValue(), AvatarInventoryType.BodyParts)), - inventory.stream().map(f -> (Map) f.getValue()).map(f -> Triplet.with(((Number) f.get("Id").getValue()).longValue(), f.get("Color").getValue(), AvatarInventoryType.Clothes)) + inventory.stream().map(f -> (Map) f.getValue()).map(f -> Triplet.with(((Number) f.get("Id").getValue()).longValue(), f.get("Color").getValue(), AvatarInventoryType.fromGoodId(goodsService, ((Number) f.get("Id").getValue()).longValue()))) ).collect(Collectors.toList()); users.resetUsedClothes(playerId); diff --git a/src/main/java/com/alterdekim/game/component/game/AvatarInventoryType.java b/src/main/java/com/alterdekim/game/component/game/AvatarInventoryType.java index 829b6c2..b5bb738 100644 --- a/src/main/java/com/alterdekim/game/component/game/AvatarInventoryType.java +++ b/src/main/java/com/alterdekim/game/component/game/AvatarInventoryType.java @@ -1,42 +1,58 @@ package com.alterdekim.game.component.game; +import com.alterdekim.game.entity.Good; +import com.alterdekim.game.service.GoodsService; +import lombok.Getter; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import java.util.Collections; import java.util.List; +import java.util.Optional; +@Slf4j @RequiredArgsConstructor +@Getter public enum AvatarInventoryType { - Clothes(List.of(1, 4, 14, 32, 36, 40)), - Magic(Collections.singletonList(64)), - Backgrounds(Collections.singletonList(41)), - Phones(Collections.emptyList()), - Smile(Collections.emptyList()), - House(Collections.singletonList(34)), - HouseFurniture(Collections.singletonList(20)), - Club(Collections.singletonList(58)), - ClubFacade(Collections.singletonList(63)), - ClubShow(Collections.singletonList(78)), - ClubFurniture(Collections.singletonList(59)), - ClubInstruments(Collections.singletonList(105)), - ClubDigitalStuff(Collections.singletonList(68)), - ClubFloor(Collections.singletonList(61)), - ClubWallpaper(Collections.singletonList(62)), - ClubGames(Collections.singletonList(107)), - ClubFood(Collections.singletonList(67)), - ClubBeverages(Collections.singletonList(66)), - ClubDeserts(Collections.singletonList(65)), - Achievements(Collections.emptyList()), - BodyParts(Collections.emptyList()); + Clothes_(1), + Caps(4), + Glasses(14), + Boots(32), + Bangles(36), + Suits(40), + Magic(64), + Backgrounds(41), + Phones(-4), + Smile(-5), + House(34), + HouseFurniture(20), + Club(58), + ClubFacade(63), + ClubShow(78), + ClubFurniture(59), + ClubInstruments(105), + ClubDigitalStuff(68), + ClubFloor(61), + ClubWallpaper(62), + ClubGames(107), + ClubFood(67), + ClubBeverages(66), + ClubDeserts(65), + Achievements(-1), + BodyParts(-2), + Unknown(-3); - private final List goodTypes; + private final Integer goodType; public static AvatarInventoryType fromGoodType(int goodType) { for( AvatarInventoryType t : values() ) { - for( Integer gt : t.goodTypes ) { - if( goodType == gt) return t; - } + if( goodType == t.goodType ) return t; } - return Clothes; + return Unknown; + } + + public static AvatarInventoryType fromGoodId(GoodsService goodsService, long goodId) { + Integer goodType = goodsService.findById(goodId).map(Good::getGoodTypeId).orElse(-3); + return fromGoodType(goodType); } } diff --git a/src/main/java/com/alterdekim/game/component/game/avatar/GoodClothType.java b/src/main/java/com/alterdekim/game/component/game/avatar/GoodClothType.java index 03da60e..e3aeeeb 100644 --- a/src/main/java/com/alterdekim/game/component/game/avatar/GoodClothType.java +++ b/src/main/java/com/alterdekim/game/component/game/avatar/GoodClothType.java @@ -1,19 +1,20 @@ package com.alterdekim.game.component.game.avatar; +import com.alterdekim.game.component.game.AvatarInventoryType; import lombok.AllArgsConstructor; import lombok.Getter; @Getter @AllArgsConstructor public enum GoodClothType { - Clothes(1, 212, 36, 120), - Caps(4, 211, 45, 21), - Glasses(14, 210, 31, 62), - Boots(32, 213, 11, 123), - Bangles(36, 214, 56, 24), - Suits(40, 429, 27, 697); + Clothes(AvatarInventoryType.Clothes_, 212, 36, 120), + Caps(AvatarInventoryType.Caps, 211, 45, 21), + Glasses(AvatarInventoryType.Glasses, 210, 31, 62), + Boots(AvatarInventoryType.Boots, 213, 11, 123), + Bangles(AvatarInventoryType.Bangles, 214, 56, 24), + Suits(AvatarInventoryType.Suits, 429, 27, 697); - private final int val; + private final AvatarInventoryType val; private final long tabMediaResourceId; private final int layerId; private final int textResourceId; diff --git a/src/main/java/com/alterdekim/game/controller/SignUpController.java b/src/main/java/com/alterdekim/game/controller/SignUpController.java index 9570137..3109e65 100644 --- a/src/main/java/com/alterdekim/game/controller/SignUpController.java +++ b/src/main/java/com/alterdekim/game/controller/SignUpController.java @@ -9,6 +9,7 @@ import com.alterdekim.game.entity.User; import com.alterdekim.game.repository.UserRepository; import com.alterdekim.game.security.AuthenticationUtil; import com.alterdekim.game.service.AvatarInventoryService; +import com.alterdekim.game.service.GoodsService; import com.alterdekim.game.service.IncompatibleService; import com.alterdekim.game.service.UserService; import com.fasterxml.jackson.annotation.JsonAutoDetect; @@ -30,6 +31,8 @@ import java.util.Base64; import java.util.List; import java.util.Optional; +import static com.alterdekim.game.utils.GameUtils.EmptyGoodId; + @Slf4j @Controller public class SignUpController { @@ -46,6 +49,9 @@ public class SignUpController { @Autowired private UserService userService; + @Autowired + private GoodsService goodsService; + @PostMapping("/ConstructorACHandler.ashx") public ResponseEntity avatarController() { @@ -105,13 +111,13 @@ public class SignUpController { try { av.getInventory() .stream() - .filter(i -> i.getID() != 98) - .map(i -> new AvatarInventory(referenceLoader.getUserReference(userId), i.getID().longValue(), true, AvatarInventoryType.Clothes, 0)) + .filter(i -> i.getID() != EmptyGoodId.intValue()) + .map(i -> new AvatarInventory(referenceLoader.getUserReference(userId), i.getID().longValue(), true, AvatarInventoryType.fromGoodId(goodsService, i.getID()), 0)) .forEach(i -> avatarInventoryService.addGoodToInventory(i)); av.getBodyParts() .stream() - .filter(i -> i.getID() != 98) + .filter(i -> i.getID() != EmptyGoodId.intValue()) .map(i -> new AvatarInventory(referenceLoader.getUserReference(userId), i.getID().longValue(), true, AvatarInventoryType.BodyParts, i.getColor() == null ? 0 : i.getColor())) .forEach(i -> avatarInventoryService.addGoodToInventory(i)); } catch (Exception e) { diff --git a/src/main/java/com/alterdekim/game/message/amf/AMFSerializer.java b/src/main/java/com/alterdekim/game/message/amf/AMFSerializer.java index 48094f1..334ddfd 100644 --- a/src/main/java/com/alterdekim/game/message/amf/AMFSerializer.java +++ b/src/main/java/com/alterdekim/game/message/amf/AMFSerializer.java @@ -27,8 +27,8 @@ public class AMFSerializer { if( obj == null ) return new ArrayList<>(Collections.singletonList((byte) 0x05)); return switch (obj.getClass().getSimpleName()) { case "String" -> serializeString((String) obj); - case "Integer", "Double", "Float", "Long", "Short", "Byte" -> serializeNumber(((java.lang.Number) obj).doubleValue()); - case "Boolean" -> serializeBoolean((Boolean) obj); + case "Integer", "int", "Double", "double", "Float", "float", "Long", "long", "Short", "short", "Byte", "byte" -> serializeNumber(((java.lang.Number) obj).doubleValue()); + case "Boolean", "boolean" -> serializeBoolean((Boolean) obj); case "Map", "HashMap" -> serializeMap((Map) obj); case "List", "ArrayList" -> serializeArray((List) obj); default -> isStream ? serializeJavaObjectAsStream(obj) : serializeJavaObjectAsKeyVal(obj); diff --git a/src/main/java/com/alterdekim/game/repository/AvatarInventoryRepository.java b/src/main/java/com/alterdekim/game/repository/AvatarInventoryRepository.java index ccd6100..743ef02 100644 --- a/src/main/java/com/alterdekim/game/repository/AvatarInventoryRepository.java +++ b/src/main/java/com/alterdekim/game/repository/AvatarInventoryRepository.java @@ -61,7 +61,7 @@ public interface AvatarInventoryRepository extends JpaRepository findInventoryItems(@Param("uid") Long userId, @Param("goodTypeId") GoodClothType goodClothType); @Query(value = """ @@ -130,9 +130,9 @@ public interface AvatarInventoryRepository extends JpaRepository findUsedClothesByUserId(@Param("uid") Long userId); + List findUsedClothesByUserId(@Param("uid") Long userId, @Param("goodTypeId") GoodClothType goodClothType); @Query(value = """ diff --git a/src/main/java/com/alterdekim/game/service/AvatarInventoryService.java b/src/main/java/com/alterdekim/game/service/AvatarInventoryService.java index a8532e7..decefc3 100644 --- a/src/main/java/com/alterdekim/game/service/AvatarInventoryService.java +++ b/src/main/java/com/alterdekim/game/service/AvatarInventoryService.java @@ -20,6 +20,9 @@ import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; +import static com.alterdekim.game.utils.GameUtils.EmptyGoodId; +import static com.alterdekim.game.utils.GameUtils.EmptyMRId; + @Slf4j @Service public class AvatarInventoryService { @@ -85,7 +88,7 @@ public class AvatarInventoryService { addEmpty ? Stream.of(bodyPartRepository.findInventoryItems(userId, type), Collections.singletonList(new InventoryItem() { @Override public Long getId() { - return 98L; + return EmptyGoodId; } @Override @@ -95,12 +98,12 @@ public class AvatarInventoryService { @Override public Long getBodyPartId() { - return 98L; + return EmptyGoodId; } @Override public Integer getMediaResourceId() { - return 98; + return EmptyMRId; } @Override @@ -148,7 +151,7 @@ public class AvatarInventoryService { public InventoryGroup getClothInventoryGroup(Long userId, GoodClothType type) { return new InventoryGroup( - type.getVal(), + type.getVal().getGoodType(), type.getTextResourceId(), false, 0, @@ -158,7 +161,13 @@ public class AvatarInventoryService { } public List getWholeAvatarByUserId(Long userId) { - return Stream.of(this.inventoryRepository.findUsedBodyPartsByUserId(userId), this.inventoryRepository.findUsedClothesByUserId(userId)) + return Stream.of(this.inventoryRepository.findUsedBodyPartsByUserId(userId), + this.inventoryRepository.findUsedClothesByUserId(userId, GoodClothType.Clothes), + this.inventoryRepository.findUsedClothesByUserId(userId, GoodClothType.Caps), + this.inventoryRepository.findUsedClothesByUserId(userId, GoodClothType.Glasses), + this.inventoryRepository.findUsedClothesByUserId(userId, GoodClothType.Bangles), + this.inventoryRepository.findUsedClothesByUserId(userId, GoodClothType.Boots), + this.inventoryRepository.findUsedClothesByUserId(userId, GoodClothType.Suits)) .flatMap(List::stream).collect(Collectors.toList()); } @@ -245,7 +254,7 @@ public class AvatarInventoryService { isShape ? this.getAvatarBodyPartsByType(type) : Stream.of( this.getAvatarBodyPartsByType(type), Collections.singletonList( - new AvatarBodyPart(98, 0, true, this.resourceService.getUrlByMediaResourceId(98L).get()) + new AvatarBodyPart(EmptyGoodId.intValue(), 0, true, this.resourceService.getUrlByMediaResourceId(EmptyMRId.longValue()).get()) ) ) .flatMap(Collection::stream) @@ -265,7 +274,7 @@ public class AvatarInventoryService { } private List getRandomStuffByGoodType(GoodClothType type) { - List g = this.goodRepository.findByGoodTypeId(type.getVal()); + List g = this.goodRepository.findByGoodTypeId(type.getVal().getGoodType()); int l = (int) Math.round(Math.random() * (g.size() - 4)); return g.subList(l, l+3) .stream() @@ -284,14 +293,14 @@ public class AvatarInventoryService { for( GoodClothType type : GoodClothType.values() ) { groups.add( new AvatarBodyPartGroup( - type.getVal(), + type.getVal().getGoodType(), type.name(), resourceService.getUrlByMediaResourceId(type.getTabMediaResourceId()).get(), type.getLayerId(), Stream.of( this.getRandomStuffByGoodType(type), Collections.singletonList( - new AvatarBodyPart(98, 0, true, this.resourceService.getUrlByMediaResourceId(98L).get()) + new AvatarBodyPart(EmptyGoodId.intValue(), 0, true, this.resourceService.getUrlByMediaResourceId(EmptyMRId.longValue()).get()) ) ) .flatMap(Collection::stream) diff --git a/src/main/java/com/alterdekim/game/service/UserService.java b/src/main/java/com/alterdekim/game/service/UserService.java index a4f14d4..1d1533b 100644 --- a/src/main/java/com/alterdekim/game/service/UserService.java +++ b/src/main/java/com/alterdekim/game/service/UserService.java @@ -198,7 +198,12 @@ public class UserService { public void resetUsedClothes(Long userId) { this.inventoryService.resetUsed(userId, AvatarInventoryType.BodyParts); - this.inventoryService.resetUsed(userId, AvatarInventoryType.Clothes); + this.inventoryService.resetUsed(userId, AvatarInventoryType.Clothes_); + this.inventoryService.resetUsed(userId, AvatarInventoryType.Caps); + this.inventoryService.resetUsed(userId, AvatarInventoryType.Glasses); + this.inventoryService.resetUsed(userId, AvatarInventoryType.Suits); + this.inventoryService.resetUsed(userId, AvatarInventoryType.Bangles); + this.inventoryService.resetUsed(userId, AvatarInventoryType.Boots); } public UserPhone getUserPhoneByUserId(Long userId) { diff --git a/src/main/java/com/alterdekim/game/utils/GameUtils.java b/src/main/java/com/alterdekim/game/utils/GameUtils.java index d30adf9..5f0aa79 100644 --- a/src/main/java/com/alterdekim/game/utils/GameUtils.java +++ b/src/main/java/com/alterdekim/game/utils/GameUtils.java @@ -1,6 +1,9 @@ package com.alterdekim.game.utils; public class GameUtils { + + public static final Long EmptyGoodId = 360L; + public static final Integer EmptyMRId = 98; public static int extractLocationId(String s) { String[] r = s.split("\\$"); if( r.length < 3) return 0;