Changed AMFObject value conversion

This commit is contained in:
Michael Wain 2025-03-06 16:27:35 +03:00
parent 9c8de427ef
commit 25f5e2603e
4 changed files with 86 additions and 45 deletions

View File

@ -79,7 +79,7 @@ public class GameServer {
public void onMessage(int playerId, List<AMFObject> params ) { public void onMessage(int playerId, List<AMFObject> params ) {
try { try {
log.info("GameServer.onMessage() pid: {}, params: {}", playerId, params); log.info("GameServer.onMessage() pid: {}, params: {}", playerId, params);
switch(CommandType.fromString( (String) params.get(0).getValue() )) { switch(CommandType.fromString( params.get(0).toString() )) {
case UserCommand: case UserCommand:
processUserMessage(playerId, AMFMapper.deobfuscate(params.subList(1, params.size()), UserMessage.class)); processUserMessage(playerId, AMFMapper.deobfuscate(params.subList(1, params.size()), UserMessage.class));
break; break;
@ -102,8 +102,8 @@ public class GameServer {
private void setPlayerAvatarPosition(int playerId, SetPlayerAvatarPosition message) { private void setPlayerAvatarPosition(int playerId, SetPlayerAvatarPosition message) {
if( message.getCoordinates() != null ) { if( message.getCoordinates() != null ) {
players.get(playerId).setX((Double) message.getCoordinates().get("x").getValue()); players.get(playerId).setX(message.getCoordinates().get("x").getDouble());
players.get(playerId).setY((Double) message.getCoordinates().get("y").getValue()); players.get(playerId).setY(message.getCoordinates().get("y").getDouble());
} }
this.sendInPlayersLocation(playerId, CommandType.SetUserAvatarPosition, this.sendInPlayersLocation(playerId, CommandType.SetUserAvatarPosition,
new SetPlayerPosition( new SetPlayerPosition(
@ -131,16 +131,16 @@ public class GameServer {
case UserFriendsGet, GetOnlineUserFriends -> this.sendResult(playerId, message.getTransactionId(), users.getFriendsOfUser(playerId, players)); case UserFriendsGet, GetOnlineUserFriends -> this.sendResult(playerId, message.getTransactionId(), users.getFriendsOfUser(playerId, players));
case UserFriendsRequests -> this.sendResult(playerId, message.getTransactionId(), users.getRequestsOfUser(playerId, players)); case UserFriendsRequests -> this.sendResult(playerId, message.getTransactionId(), users.getRequestsOfUser(playerId, players));
case RevokeUserFriendship -> { case RevokeUserFriendship -> {
users.removeFriendshipWithUser(playerId, Integer.parseInt((String) message.getArguments().get(0).getValue())); users.removeFriendshipWithUser(playerId, message.getArguments().get(0).getInt());
this.call(Integer.parseInt((String) message.getArguments().get(0).getValue()), CommandType.OnFriendsRemoved, playerId); this.call(message.getArguments().get(0).getInt(), CommandType.OnFriendsRemoved, playerId);
} }
case ApplyUserFriendship -> this.applyUserFriendship(playerId, (String) message.getArguments().get(0).getValue(), (String) message.getArguments().get(1).getValue()); case ApplyUserFriendship -> this.applyUserFriendship(playerId, message.getArguments().get(0).toString(), message.getArguments().get(1).toString());
case GetClubMap -> // todo: implement case GetClubMap -> // todo: implement
this.sendResult(playerId, message.getTransactionId(), "</clubmap>"); this.sendResult(playerId, message.getTransactionId(), "</clubmap>");
case GetFriendPanelData -> this.sendResult(playerId, message.getTransactionId(), ""); case GetFriendPanelData -> this.sendResult(playerId, message.getTransactionId(), "");
case UpdateUserData -> this.sendResult(playerId, message.getTransactionId(), null); case UpdateUserData -> this.sendResult(playerId, message.getTransactionId(), null);
case GetUserLocation -> { case GetUserLocation -> {
double prevLocation = (Double) message.getArguments().get(2).getValue(); double prevLocation = message.getArguments().get(2).getDouble();
if (prevLocation == 0.0d) { if (prevLocation == 0.0d) {
this.sendResult(playerId, this.sendResult(playerId,
message.getTransactionId(), message.getTransactionId(),
@ -150,9 +150,9 @@ public class GameServer {
); );
return; return;
} }
long requestedLocation = ((Number) message.getArguments().get(1).getValue()).longValue(); long requestedLocation = message.getArguments().get(1).getLong();
if( requestedLocation == -1L ) { if( requestedLocation == -1L ) {
int homePlayerId = Integer.parseInt((String) message.getArguments().get(0).getValue()); int homePlayerId = message.getArguments().get(0).getInt();
this.players.get(playerId).setHomeId(homePlayerId); this.players.get(playerId).setHomeId(homePlayerId);
this.sendResult(playerId, message.getTransactionId(), xmlMapper.writeValueAsString(locationService.getHomeByUserId(homePlayerId))); this.sendResult(playerId, message.getTransactionId(), xmlMapper.writeValueAsString(locationService.getHomeByUserId(homePlayerId)));
return; return;
@ -164,20 +164,20 @@ public class GameServer {
this.sendResult(playerId, message.getTransactionId(), xmlMapper.writeValueAsString(locationService.getLocationById(requestedLocation))); this.sendResult(playerId, message.getTransactionId(), xmlMapper.writeValueAsString(locationService.getLocationById(requestedLocation)));
} }
case GetUserLocationById -> { case GetUserLocationById -> {
long nextLocation = ((Number) message.getArguments().get(1).getValue()).longValue(); long nextLocation = message.getArguments().get(1).getLong();
if (nextLocation == -1) { if (nextLocation == -1) {
nextLocation = 0; nextLocation = 0;
} }
this.sendResult(playerId, message.getTransactionId(), xmlMapper.writeValueAsString(locationService.getLocationById(nextLocation))); this.sendResult(playerId, message.getTransactionId(), xmlMapper.writeValueAsString(locationService.getLocationById(nextLocation)));
} }
case ChatMessage -> { case ChatMessage -> {
String text = (String) message.getArguments().get(1).getValue(); String text = message.getArguments().get(1).toString();
sendInPlayersLocation(playerId, CommandType.ChatMessage, new ChatMessage(playerId, text)); sendInPlayersLocation(playerId, CommandType.ChatMessage, new ChatMessage(playerId, text));
} }
case Shoot -> { case Shoot -> {
if (message.getSrv().equals("ROOM")) { if (message.getSrv().equals("ROOM")) {
double x = (double) message.getArguments().get(1).getValue(); double x = message.getArguments().get(1).getDouble();
double y = (double) message.getArguments().get(2).getValue(); double y = message.getArguments().get(2).getDouble();
sendInPlayersLocation(playerId, CommandType.Shoot, new Shoot(playerId, x, y)); sendInPlayersLocation(playerId, CommandType.Shoot, new Shoot(playerId, x, y));
break; break;
} }
@ -186,26 +186,26 @@ public class GameServer {
); );
this.users.setWeaponsCount(playerId, this.users.getIntegerUserProperty(playerId, PlayerProperties.WeaponsCount, 15) - 1); this.users.setWeaponsCount(playerId, this.users.getIntegerUserProperty(playerId, PlayerProperties.WeaponsCount, 15) - 1);
} }
case GetUserInfo -> getUserInfo(playerId, ((Double) message.getArguments().get(0).getValue()).intValue(), message); case GetUserInfo -> getUserInfo(playerId, message.getArguments().get(0).getInt(), message);
case GetUserAvatar -> getAvatar(playerId, message); case GetUserAvatar -> getAvatar(playerId, message);
case SaveUserAvatarChanges -> saveAvatar(playerId, message); case SaveUserAvatarChanges -> saveAvatar(playerId, message);
case GetUserUnlocks -> this.sendResult(playerId, message.getTransactionId(), "123"); case GetUserUnlocks -> this.sendResult(playerId, message.getTransactionId(), "123");
case GetSnInvitePanelData -> {} case GetSnInvitePanelData -> {}
case GetGrantBlocks -> {} case GetGrantBlocks -> {}
case UseMagicAbility -> this.sendInPlayersLocation(playerId, CommandType.UseMagicAbility, new UseMagicAbility( case UseMagicAbility -> this.sendInPlayersLocation(playerId, CommandType.UseMagicAbility, new UseMagicAbility(
Integer.parseInt((String) message.getArguments().get(0).getValue()), message.getArguments().get(0).getInt(),
((Double) message.getArguments().get(1).getValue()).intValue() message.getArguments().get(1).getInt()
)); ));
case SetDefaultUserPhone -> { case SetDefaultUserPhone -> {
long phoneId = ((Double) message.getArguments().get(0).getValue()).longValue(); long phoneId = message.getArguments().get(0).getLong();
this.users.setDefaultPhone(playerId, phoneId); this.users.setDefaultPhone(playerId, phoneId);
} }
case SetUserBackground -> { case SetUserBackground -> {
long bgId = ((Double) message.getArguments().get(0).getValue()).longValue(); long bgId = message.getArguments().get(0).getLong();
this.users.setDefaultBackground(playerId, bgId); this.users.setDefaultBackground(playerId, bgId);
} }
case QueryUserFriendship -> { case QueryUserFriendship -> {
int participantId = ((Double) message.getArguments().get(0).getValue()).intValue(); int participantId = message.getArguments().get(0).getInt();
relationshipService.sendRequest(playerId, participantId); relationshipService.sendRequest(playerId, participantId);
this.call(participantId, CommandType.OnFriendshipRequestAdded, this.call(participantId, CommandType.OnFriendshipRequestAdded,
new OneFR( new OneFR(
@ -218,9 +218,9 @@ public class GameServer {
this.sendResult(playerId, message.getTransactionId(), balance); this.sendResult(playerId, message.getTransactionId(), balance);
} }
case PhoneMessage -> { case PhoneMessage -> {
int receiverId = message.getArguments().get(0).getType() == AMFValueType.NUMBER ? ((Double) message.getArguments().get(0).getValue()).intValue() : Integer.parseInt((String) message.getArguments().get(0).getValue()); int receiverId = message.getArguments().get(0).getInt();
if (receiverId <= 0) return; if (receiverId <= 0) return;
String messageText = ((String) message.getArguments().get(1).getValue()); String messageText = message.getArguments().get(1).toString();
PhoneMessage pm = new PhoneMessage(); PhoneMessage pm = new PhoneMessage();
pm.setText(messageText); pm.setText(messageText);
pm.setSenderId(playerId); pm.setSenderId(playerId);
@ -232,17 +232,17 @@ public class GameServer {
this.call(receiverId, CommandType.AddNewPhoneMessage, xmlMapper.writeValueAsString(pm)); this.call(receiverId, CommandType.AddNewPhoneMessage, xmlMapper.writeValueAsString(pm));
} }
case MarkPhoneMessageAsRead -> { case MarkPhoneMessageAsRead -> {
Long messageId = ((Double) message.getArguments().get(0).getValue()).longValue(); Long messageId = message.getArguments().get(0).getLong();
phoneMessageService.markAsRead(messageId); phoneMessageService.markAsRead(messageId);
} }
case DeletePhoneMessage -> { case DeletePhoneMessage -> {
Long messageId1 = ((Double) message.getArguments().get(0).getValue()).longValue(); Long messageId1 = message.getArguments().get(0).getLong();
phoneMessageService.removeById(messageId1); phoneMessageService.removeById(messageId1);
} }
case CardMessage -> { case CardMessage -> {
if( !subtractUsualTickets(playerId, 20) ) return; if( !subtractUsualTickets(playerId, 20) ) return;
int receiverId = ((Number) message.getArguments().get(0).getValue()).intValue(); int receiverId = message.getArguments().get(0).getInt();
int postcardId = ((Number) message.getArguments().get(1).getValue()).intValue(); int postcardId = message.getArguments().get(1).getInt();
Postcard postcard = new Postcard(); Postcard postcard = new Postcard();
postcard.setIsNew(true); postcard.setIsNew(true);
postcard.setDateSent(""); postcard.setDateSent("");
@ -254,15 +254,15 @@ public class GameServer {
this.call(receiverId, CommandType.CardMessage, xmlMapper.writeValueAsString(postcard)); this.call(receiverId, CommandType.CardMessage, xmlMapper.writeValueAsString(postcard));
} }
case MarkCardMessageAsRead -> { case MarkCardMessageAsRead -> {
long postcardMessageId = ((Number) message.getArguments().get(0).getValue()).longValue(); long postcardMessageId = message.getArguments().get(0).getLong();
this.postcardService.markAsRead(postcardMessageId); this.postcardService.markAsRead(postcardMessageId);
} }
case DeleteCardMessage -> { case DeleteCardMessage -> {
long postcardMessageId = ((Number) message.getArguments().get(0).getValue()).longValue(); long postcardMessageId = message.getArguments().get(0).getLong();
this.postcardService.removeById(postcardMessageId); this.postcardService.removeById(postcardMessageId);
} }
case BuyBatch -> buySomething(playerId, message.getArguments().get(0), message); case BuyBatch -> buySomething(playerId, message.getArguments().get(0), message);
case LockHouse -> lockSomething(playerId, ((Number) message.getArguments().get(0).getValue()).intValue(), (Boolean) message.getArguments().get(1).getValue(), message); case LockHouse -> lockSomething(playerId, message.getArguments().get(0).getInt(), message.getArguments().get(1).getBoolean(), message);
} }
} }
@ -276,14 +276,14 @@ public class GameServer {
} }
private void buySomething(int playerId, AMFObject obj, UserMessage message) { private void buySomething(int playerId, AMFObject obj, UserMessage message) {
List<AMFObject> array = (List<AMFObject>) obj.getValue(); List<AMFObject> array = (List<AMFObject>) obj.getRaw();
array.forEach(i -> this.buyOne(playerId, i, message)); array.forEach(i -> this.buyOne(playerId, i, message));
} }
private void buyOne(int playerId, AMFObject item, UserMessage message) { private void buyOne(int playerId, AMFObject item, UserMessage message) {
Map<String, AMFObject> obj = (Map<String, AMFObject>) item.getValue(); Map<String, AMFObject> obj = (Map<String, AMFObject>) item.getRaw();
long goodId = Long.parseLong((String) obj.get("GoodId").getValue()); long goodId = obj.get("GoodId").getLong();
boolean isMagic = ((Number) obj.get("Currency").getValue()).longValue() == 2; boolean isMagic = obj.get("Currency").getLong() == 2;
Optional<Good> tGood = this.goodsService.findById(goodId); Optional<Good> tGood = this.goodsService.findById(goodId);
if( tGood.isEmpty() ) { if( tGood.isEmpty() ) {
this.sendResult(playerId, message.getTransactionId(), new BuyGoodResult(new ArrayList<>())); this.sendResult(playerId, message.getTransactionId(), new BuyGoodResult(new ArrayList<>()));
@ -347,14 +347,14 @@ public class GameServer {
} }
private void saveAvatar(int playerId, UserMessage message) { private void saveAvatar(int playerId, UserMessage message) {
Map<String, AMFObject> changes = (Map<String, AMFObject>) message.getArguments().get(0).getValue(); Map<String, AMFObject> changes = (Map<String, AMFObject>) message.getArguments().get(0).getRaw();
List<AMFObject> bodyParts = (List<AMFObject>) changes.get("BodyParts").getValue(); List<AMFObject> bodyParts = (List<AMFObject>) changes.get("BodyParts").getRaw();
List<AMFObject> inventory = (List<AMFObject>) changes.get("Inventory").getValue(); List<AMFObject> inventory = (List<AMFObject>) changes.get("Inventory").getRaw();
List<Triplet<Long, Object, AvatarInventoryType>> l = Stream.concat( List<Triplet<Long, Object, AvatarInventoryType>> l = Stream.concat(
bodyParts.stream().map(f -> (Map<String, AMFObject>) f.getValue()).map(f -> Triplet.with(((Number) f.get("Id").getValue()).longValue(), f.get("Color").getValue(), AvatarInventoryType.BodyParts)), bodyParts.stream().map(f -> (Map<String, AMFObject>) f.getRaw()).map(f -> Triplet.with(f.get("Id").getLong(), f.get("Color").getRaw(), AvatarInventoryType.BodyParts)),
inventory.stream().map(f -> (Map<String, AMFObject>) 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()))) inventory.stream().map(f -> (Map<String, AMFObject>) f.getRaw()).map(f -> Triplet.with(f.get("Id").getLong(), f.get("Color").getRaw(), AvatarInventoryType.fromGoodId(goodsService, f.get("Id").getLong())))
).collect(Collectors.toList()); ).collect(Collectors.toList());
users.resetUsedClothes(playerId); users.resetUsedClothes(playerId);
@ -390,8 +390,8 @@ public class GameServer {
this.deleteSelf(playerId, p.getLocationId()); this.deleteSelf(playerId, p.getLocationId());
int prevLocation = p.getLocationId(); int prevLocation = p.getLocationId();
p.setLocationId(GameUtils.extractLocationId(message.getLocation())); p.setLocationId(GameUtils.extractLocationId(message.getLocation()));
p.setX((Double) message.getCoordinates().get("x").getValue()); p.setX(message.getCoordinates().get("x").getDouble());
p.setY((Double) message.getCoordinates().get("y").getValue()); p.setY(message.getCoordinates().get("y").getDouble());
p.setState(message.getStartState()); p.setState(message.getStartState());
this.updateLocationPlayers(playerId, prevLocation); this.updateLocationPlayers(playerId, prevLocation);
this.sendResult(playerId, message.getTransactionId(), ""); this.sendResult(playerId, message.getTransactionId(), "");

View File

@ -166,9 +166,9 @@ public class ConnectedProcessor extends ConnectionProcessor {
List<AMFObject> mr = AMFDeserializer.newInstance(message).deserialize(); List<AMFObject> mr = AMFDeserializer.newInstance(message).deserialize();
if( !mr.isEmpty() && if( !mr.isEmpty() &&
mr.get(0).getType() == AMFValueType.STRING && mr.get(0).getType() == AMFValueType.STRING &&
mr.get(0).getValue().equals("connect") ) { mr.get(0).toString().equals("connect") ) {
this.playerId = Integer.parseInt((String) mr.get(3).getValue()); this.playerId = mr.get(3).getInt();
this.gameServer.onConnect(this.playerId, (String) mr.get(5).getValue(), this); this.gameServer.onConnect(this.playerId, mr.get(5).toString(), this);
this.getOutputStream().write( StringUtils.hexStringToByteArray("020000000000040500000000002625A0020000000000050600000000002625A00202000000000004010000000000001000030000000000F214000000000200075F726573756C74003FF0000000000000030006666D7356657202000E464D532F342C302C302C31313231000C6361706162696C697469657300406FE0000000000000046D6F6465003FF00000000000000000090300056C6576656C0200067374617475730004636F646502001D4E6574436F6E6E656374696F6E2E436F6E6E6563742E53756363657373000B6465736372697074696F6E020015436F6E6E656374696F6E207375636365656465642E000E6F626A656374456E636F64696E670000000000000000000004646174610800000000000776657273696F6E02000A342C302C302C31313231000009000009") ); this.getOutputStream().write( StringUtils.hexStringToByteArray("020000000000040500000000002625A0020000000000050600000000002625A00202000000000004010000000000001000030000000000F214000000000200075F726573756C74003FF0000000000000030006666D7356657202000E464D532F342C302C302C31313231000C6361706162696C697469657300406FE0000000000000046D6F6465003FF00000000000000000090300056C6576656C0200067374617475730004636F646502001D4E6574436F6E6E656374696F6E2E436F6E6E6563742E53756363657373000B6465736372697074696F6E020015436F6E6E656374696F6E207375636365656465642E000E6F626A656374456E636F64696E670000000000000000000004646174610800000000000776657273696F6E02000A342C302C302C31313231000009000009") );
this.getOutputStream().flush(); this.getOutputStream().flush();

View File

@ -15,7 +15,7 @@ public class AMFMapper {
.findFirst() .findFirst()
.orElse(null); .orElse(null);
if( object == null ) continue; if( object == null ) continue;
field.set(obj, object.getValue()); field.set(obj, object.getRaw());
objects.remove(object); objects.remove(object);
} }
return obj; return obj;

View File

@ -2,12 +2,53 @@ package com.alterdekim.game.message.amf;
import lombok.*; import lombok.*;
@Getter
@Setter @Setter
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@ToString
public class AMFObject { public class AMFObject {
@Getter
private AMFValueType type; private AMFValueType type;
private Object value; private Object value;
public long getLong() {
return switch (type) {
case STRING -> Long.parseLong((String) this.value);
case NUMBER -> ((Number) this.value).longValue();
default -> 0L;
};
}
public int getInt() {
return switch (type) {
case STRING -> Integer.parseInt((String) this.value);
case NUMBER -> ((Number) this.value).intValue();
default -> 0;
};
}
public double getDouble() {
return switch (type) {
case STRING -> Double.parseDouble((String) this.value);
case NUMBER -> ((Number) this.value).doubleValue();
default -> 0;
};
}
public boolean getBoolean() {
return type == AMFValueType.BOOLEAN ? (Boolean) this.value : false;
}
public Object getRaw() {
return this.value;
}
@Override
public String toString() {
return switch (this.type) {
case STRING -> (String) this.value;
case NULL -> "null";
default -> this.value.toString();
};
}
} }