mirror of
https://github.com/kuroppoi/entralinked.git
synced 2026-04-25 15:47:00 -05:00
Merge 196bf7e861 into b37f8b5624
This commit is contained in:
commit
4e03f31e6d
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -10,3 +10,6 @@ testRun
|
|||
.project
|
||||
.classpath
|
||||
bin
|
||||
|
||||
# IntelliJ
|
||||
.idea
|
||||
|
|
|
|||
|
|
@ -66,8 +66,9 @@ public class PkmnInfoReader {
|
|||
int form = (buffer.getByte(64) >> 3) & 0x1F;
|
||||
boolean genderless = ((buffer.getByte(64) >> 2) & 1) == 1;
|
||||
boolean female = ((buffer.getByte(64) >> 1) & 1) == 1;
|
||||
int natureByte = buffer.getByte(65);
|
||||
PkmnGender gender = genderless ? PkmnGender.GENDERLESS : female ? PkmnGender.FEMALE : PkmnGender.MALE;
|
||||
PkmnNature nature = PkmnNature.valueOf(buffer.getByte(65));
|
||||
PkmnNature nature = PkmnNature.valueOf(natureByte);
|
||||
String nickname = getString(buffer, 72, 20);
|
||||
String trainerName = getString(buffer, 104, 14);
|
||||
|
||||
|
|
@ -75,13 +76,13 @@ public class PkmnInfoReader {
|
|||
if(!buffer.release()) {
|
||||
logger.warn("Buffer was not deallocated!");
|
||||
}
|
||||
|
||||
|
||||
// Loosely verify data
|
||||
if(species < 1 || species > 649) throw new IOException("Invalid species");
|
||||
if(heldItem < 0 || heldItem > 638) throw new IOException("Invalid held item");
|
||||
if(ability < 1 || ability > 164) throw new IOException("Invalid ability");
|
||||
if(level < 1 || level > 100) throw new IOException("Level is out of range");
|
||||
if(nature == null) throw new IOException("Invalid nature");
|
||||
if(species < 1 || species > 649) throw new IOException(String.format("Invalid species: %d", species));
|
||||
if(heldItem < 0 || heldItem > 638) throw new IOException(String.format("Invalid held item: %d", heldItem));
|
||||
if(ability < 1 || ability > 164) throw new IOException(String.format("Invalid ability: %d", ability));
|
||||
if(level < 1 || level > 100) throw new IOException(String.format("Level is out of range: %d", level));
|
||||
if(nature == null) throw new IOException(String.format("Invalid nature: %d", natureByte));
|
||||
|
||||
// Create record
|
||||
return new PkmnInfo(nickname, trainerName, nature, gender, species, personality,
|
||||
|
|
|
|||
18
src/main/java/entralinked/model/player/GymBadge.java
Normal file
18
src/main/java/entralinked/model/player/GymBadge.java
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
package entralinked.model.player;
|
||||
|
||||
public enum GymBadge {
|
||||
BADGE_ONE(0b00000001),
|
||||
BADGE_TWO(0b00000010),
|
||||
BADGE_THREE(0b00000100),
|
||||
BADGE_FOUR(0b00001000),
|
||||
BADGE_FIVE(0b00010000),
|
||||
BADGE_SIX(0b00100000),
|
||||
BADGE_SEVEN(0b01000000),
|
||||
BADGE_EIGHT(0b10000000);
|
||||
|
||||
public final int mask;
|
||||
|
||||
GymBadge(int mask) {
|
||||
this.mask = mask;
|
||||
}
|
||||
}
|
||||
29
src/main/java/entralinked/model/player/Offsets.java
Normal file
29
src/main/java/entralinked/model/player/Offsets.java
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
package entralinked.model.player;
|
||||
|
||||
import entralinked.GameVersion;
|
||||
|
||||
public class Offsets {
|
||||
public static final int TRAINER_INFO = 0x19400;
|
||||
public static final int TRAINER_INFO_SIZE = 0x67;
|
||||
public static final int TRAINER_NAME_SUB_OFFSET = 0x4;
|
||||
public static final byte TRAINER_NAME_SIZE = 0x10;
|
||||
public static final int TRAINER_ID_SUB_OFFSET = 0x14;
|
||||
public static final int SECRET_ID_SUB_OFFSET = 0x16;
|
||||
public static final int COUNTRY_SUB_OFFSET = 0x1C;
|
||||
public static final int REGION_SUB_OFFSET = 0x1D;
|
||||
public static final int GENDER_OFFSET = 0x21;
|
||||
public static final int PLAYTIME_OFFSET = 0x24;
|
||||
|
||||
public static final int DREAM_WORLD_INFO = 0x1D300;
|
||||
public static final int POKEMON_INFO_SUB_OFFSET = 0x8;
|
||||
|
||||
public static final int ADVENTURE_START_TIME_OFFSET = 0x1D900;
|
||||
public static final int ADVENTURE_START_TIME_SUB_OFFSET = 0x34;
|
||||
|
||||
public static final int MONEY_AND_BADGES_VERSION_1 = 0x21200;
|
||||
public static final int MONEY_AND_BADGES_VERSION_2 = 0x21100;
|
||||
|
||||
public static int getMoneyAndBadges(GameVersion gameVersion) {
|
||||
return gameVersion.isVersion2() ? MONEY_AND_BADGES_VERSION_2 : MONEY_AND_BADGES_VERSION_1;
|
||||
}
|
||||
}
|
||||
|
|
@ -19,6 +19,7 @@ public class Player {
|
|||
private final List<DreamDecor> decor = new ArrayList<>();
|
||||
private PlayerStatus status;
|
||||
private GameVersion gameVersion;
|
||||
private TrainerInfo trainerInfo;
|
||||
private PkmnInfo dreamerInfo;
|
||||
private int levelsGained;
|
||||
private String cgearSkin;
|
||||
|
|
@ -52,10 +53,7 @@ public class Player {
|
|||
}
|
||||
|
||||
public void setEncounters(Collection<DreamEncounter> encounters) {
|
||||
if(encounters.size() <= 10) {
|
||||
this.encounters.clear();
|
||||
this.encounters.addAll(encounters);
|
||||
}
|
||||
setList(encounters, this.encounters, 10);
|
||||
}
|
||||
|
||||
public List<DreamEncounter> getEncounters() {
|
||||
|
|
@ -63,10 +61,7 @@ public class Player {
|
|||
}
|
||||
|
||||
public void setItems(Collection<DreamItem> items) {
|
||||
if(encounters.size() <= 20) {
|
||||
this.items.clear();
|
||||
this.items.addAll(items);
|
||||
}
|
||||
setList(items, this.items, 20);
|
||||
}
|
||||
|
||||
public List<DreamItem> getItems() {
|
||||
|
|
@ -74,10 +69,7 @@ public class Player {
|
|||
}
|
||||
|
||||
public void setAvenueVisitors(Collection<AvenueVisitor> avenueVisitors) {
|
||||
if(avenueVisitors.size() <= 12) {
|
||||
this.avenueVisitors.clear();
|
||||
this.avenueVisitors.addAll(avenueVisitors);
|
||||
}
|
||||
setList(avenueVisitors, this.avenueVisitors, 12);
|
||||
}
|
||||
|
||||
public List<AvenueVisitor> getAvenueVisitors() {
|
||||
|
|
@ -85,16 +77,13 @@ public class Player {
|
|||
}
|
||||
|
||||
public void setDecor(Collection<DreamDecor> decor) {
|
||||
if(decor.size() <= 5) {
|
||||
this.decor.clear();
|
||||
this.decor.addAll(decor);
|
||||
}
|
||||
setList(decor, this.decor, 5);
|
||||
}
|
||||
|
||||
|
||||
public List<DreamDecor> getDecor() {
|
||||
return Collections.unmodifiableList(decor);
|
||||
}
|
||||
|
||||
|
||||
public void setStatus(PlayerStatus status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
|
@ -102,7 +91,15 @@ public class Player {
|
|||
public PlayerStatus getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
public void setTrainerInfo(TrainerInfo trainerInfo) {
|
||||
this.trainerInfo = trainerInfo;
|
||||
}
|
||||
|
||||
public TrainerInfo getTrainerInfo() {
|
||||
return trainerInfo;
|
||||
}
|
||||
|
||||
public void setGameVersion(GameVersion gameVersion) {
|
||||
this.gameVersion = gameVersion;
|
||||
}
|
||||
|
|
@ -170,11 +167,11 @@ public class Player {
|
|||
public void setCustomMusical(String customMusical) {
|
||||
this.customMusical = customMusical;
|
||||
}
|
||||
|
||||
|
||||
public String getCustomMusical() {
|
||||
return customMusical;
|
||||
}
|
||||
|
||||
|
||||
// IO stuff
|
||||
|
||||
public void setDataDirectory(File dataDirectory) {
|
||||
|
|
@ -200,8 +197,15 @@ public class Player {
|
|||
public File getDexSkinFile() {
|
||||
return new File(dataDirectory, "zukan.bin");
|
||||
}
|
||||
|
||||
|
||||
public File getMusicalFile() {
|
||||
return new File(dataDirectory, "musical.bin");
|
||||
}
|
||||
|
||||
private static <T> void setList(Collection<T> source, List<T> target, int maxSize) {
|
||||
if(source.size() <= maxSize) {
|
||||
target.clear();
|
||||
target.addAll(source);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ public record PlayerDto(
|
|||
@JsonProperty(required = true) String gameSyncId,
|
||||
@JsonProperty(required = true) GameVersion gameVersion,
|
||||
PlayerStatus status,
|
||||
TrainerInfo trainerInfo,
|
||||
PkmnInfo dreamerInfo,
|
||||
String cgearSkin,
|
||||
String dexSkin,
|
||||
|
|
@ -31,10 +32,11 @@ public record PlayerDto(
|
|||
@JsonDeserialize(contentAs = DreamDecor.class) Collection<DreamDecor> decor) {
|
||||
|
||||
public PlayerDto(Player player) {
|
||||
this(player.getGameSyncId(), player.getGameVersion(), player.getStatus(), player.getDreamerInfo(),
|
||||
player.getCGearSkin(), player.getDexSkin(), player.getMusical(), player.getCustomCGearSkin(),
|
||||
player.getCustomDexSkin(), player.getCustomMusical(), player.getLevelsGained(), player.getEncounters(),
|
||||
player.getItems(), player.getAvenueVisitors(), player.getDecor());
|
||||
this(player.getGameSyncId(), player.getGameVersion(), player.getStatus(), player.getTrainerInfo(),
|
||||
player.getDreamerInfo(), player.getCGearSkin(), player.getDexSkin(), player.getMusical(),
|
||||
player.getCustomCGearSkin(), player.getCustomDexSkin(), player.getCustomMusical(),
|
||||
player.getLevelsGained(), player.getEncounters(), player.getItems(), player.getAvenueVisitors(),
|
||||
player.getDecor());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -44,6 +46,7 @@ public record PlayerDto(
|
|||
Player player = new Player(gameSyncId);
|
||||
player.setStatus(status);
|
||||
player.setGameVersion(gameVersion);
|
||||
player.setTrainerInfo(trainerInfo);
|
||||
player.setDreamerInfo(dreamerInfo);
|
||||
player.setCGearSkin(cgearSkin);
|
||||
player.setDexSkin(dexSkin);
|
||||
|
|
|
|||
9
src/main/java/entralinked/model/player/Playtime.java
Normal file
9
src/main/java/entralinked/model/player/Playtime.java
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
package entralinked.model.player;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
public record Playtime (
|
||||
@JsonProperty(required = true) int hours,
|
||||
@JsonProperty(required = true) int minutes,
|
||||
@JsonProperty(required = true) int seconds
|
||||
) {}
|
||||
17
src/main/java/entralinked/model/player/TrainerGender.java
Normal file
17
src/main/java/entralinked/model/player/TrainerGender.java
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
package entralinked.model.player;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonEnumDefaultValue;
|
||||
|
||||
public enum TrainerGender {
|
||||
@JsonEnumDefaultValue
|
||||
MALE,
|
||||
FEMALE;
|
||||
|
||||
public static TrainerGender valueOf(int gender) {
|
||||
return switch (gender) {
|
||||
case 0 -> MALE;
|
||||
case 1 -> FEMALE;
|
||||
default -> MALE;
|
||||
};
|
||||
}
|
||||
}
|
||||
58
src/main/java/entralinked/model/player/TrainerInfo.java
Normal file
58
src/main/java/entralinked/model/player/TrainerInfo.java
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
package entralinked.model.player;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public class TrainerInfo {
|
||||
@JsonProperty(required = false) private String trainerName;
|
||||
@JsonProperty(required = false) private int trainerId;
|
||||
@JsonProperty(required = false) private int secretId;
|
||||
@JsonProperty(required = false) private int country;
|
||||
@JsonProperty(required = false) private int region;
|
||||
@JsonProperty(required = false) private TrainerGender gender;
|
||||
@JsonProperty(required = false) private Playtime playtime;
|
||||
@JsonProperty(required = false) private long adventureStartTime;
|
||||
@JsonProperty(required = false) private long money;
|
||||
|
||||
@JsonProperty(required = false)
|
||||
@JsonDeserialize(contentAs = GymBadge.class)
|
||||
private final List<GymBadge> gymBadges = new ArrayList<>();
|
||||
|
||||
public TrainerInfo() {}
|
||||
|
||||
@JsonIgnore
|
||||
public TrainerInfo(
|
||||
String trainerName, int trainerId, int secretId, int country, int region, TrainerGender gender, Playtime playtime
|
||||
) {
|
||||
this.trainerName = trainerName;
|
||||
this.trainerId = trainerId;
|
||||
this.secretId = secretId;
|
||||
this.country = country;
|
||||
this.region = region;
|
||||
this.gender = gender;
|
||||
this.playtime = playtime;
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public void setAdventureStartTime(long adventureStartTime) {
|
||||
this.adventureStartTime = adventureStartTime;
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public void setMoney(long money) {
|
||||
this.money = money;
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public void setGymBadges(Collection<GymBadge> gymBadges) {
|
||||
if(gymBadges.size() <= 8) {
|
||||
this.gymBadges.clear();
|
||||
this.gymBadges.addAll(gymBadges);
|
||||
}
|
||||
}
|
||||
}
|
||||
103
src/main/java/entralinked/model/player/TrainerInfoReader.java
Normal file
103
src/main/java/entralinked/model/player/TrainerInfoReader.java
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
package entralinked.model.player;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.ByteBufAllocator;
|
||||
import io.netty.buffer.PooledByteBufAllocator;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class TrainerInfoReader {
|
||||
private static final int BASE_ADVENTURE_START_TIME = 946684800; // Dates are based on 2000/01/01 00:00:00
|
||||
|
||||
private static final byte ZERO_BYTE = (byte) 0x00;
|
||||
private static final byte FF_BYTE = (byte) 0xFF;
|
||||
|
||||
|
||||
private static final Logger logger = LogManager.getLogger();
|
||||
private static final ByteBufAllocator bufferAllocator = PooledByteBufAllocator.DEFAULT;
|
||||
|
||||
public static TrainerInfo readTrainerInfo(InputStream inputStream) throws IOException {
|
||||
ByteBuf buffer = bufferAllocator.buffer(Offsets.TRAINER_INFO_SIZE);
|
||||
buffer.writeBytes(inputStream, Offsets.TRAINER_INFO_SIZE);
|
||||
|
||||
String trainerName = readTrainerName(buffer);
|
||||
int trainerId = buffer.getUnsignedShortLE(Offsets.TRAINER_ID_SUB_OFFSET);
|
||||
int secretId = buffer.getUnsignedShortLE(Offsets.SECRET_ID_SUB_OFFSET);
|
||||
int country = buffer.getUnsignedByte(Offsets.COUNTRY_SUB_OFFSET);
|
||||
int region = buffer.getUnsignedByte(Offsets.REGION_SUB_OFFSET);
|
||||
TrainerGender gender = TrainerGender.valueOf(buffer.getUnsignedByte(Offsets.GENDER_OFFSET));
|
||||
Playtime playtime = readPlaytime(buffer);
|
||||
|
||||
// Try release buffer
|
||||
if(!buffer.release()) {
|
||||
logger.warn("Buffer was not deallocated!");
|
||||
}
|
||||
|
||||
return new TrainerInfo(trainerName, trainerId, secretId, country, region, gender, playtime);
|
||||
}
|
||||
|
||||
private static String readTrainerName(ByteBuf buffer) {
|
||||
StringBuilder playerName = new StringBuilder();
|
||||
for(int i = 0; i < Offsets.TRAINER_NAME_SIZE; i++) {
|
||||
byte currByte = buffer.getByte(Offsets.TRAINER_NAME_SUB_OFFSET + i);
|
||||
|
||||
if (currByte == FF_BYTE) {
|
||||
break;
|
||||
} else if (currByte != ZERO_BYTE) {
|
||||
playerName.append((char) currByte);
|
||||
}
|
||||
}
|
||||
return playerName.toString();
|
||||
}
|
||||
|
||||
private static Playtime readPlaytime(ByteBuf buffer) {
|
||||
return new Playtime(
|
||||
buffer.getUnsignedShortLE(Offsets.PLAYTIME_OFFSET),
|
||||
buffer.getUnsignedByte(Offsets.PLAYTIME_OFFSET + 2),
|
||||
buffer.getUnsignedByte(Offsets.PLAYTIME_OFFSET + 3)
|
||||
);
|
||||
}
|
||||
|
||||
public static long readAdventureStartTime(InputStream inputStream) throws IOException {
|
||||
return readLong(inputStream) + BASE_ADVENTURE_START_TIME;
|
||||
}
|
||||
|
||||
public static long readLong(InputStream inputStream) throws IOException {
|
||||
ByteBuf buffer = bufferAllocator.buffer(4);
|
||||
buffer.writeBytes(inputStream, 4);
|
||||
|
||||
long read = buffer.getUnsignedIntLE(0);
|
||||
|
||||
// Try release buffer
|
||||
if(!buffer.release()) {
|
||||
logger.warn("Buffer was not deallocated!");
|
||||
}
|
||||
|
||||
return read;
|
||||
}
|
||||
|
||||
public static List<GymBadge> readGymBadges(InputStream inputStream) throws IOException {
|
||||
ByteBuf buffer = bufferAllocator.buffer(1);
|
||||
buffer.writeBytes(inputStream, 1);
|
||||
|
||||
List<GymBadge> gymBadges = new ArrayList<>();
|
||||
int badgeFlags = buffer.getUnsignedByte(0);
|
||||
for(GymBadge badge : GymBadge.values()) {
|
||||
if ((badgeFlags & badge.mask) == badge.mask) {
|
||||
gymBadges.add(badge);
|
||||
}
|
||||
}
|
||||
|
||||
// Try release buffer
|
||||
if(!buffer.release()) {
|
||||
logger.warn("Buffer was not deallocated!");
|
||||
}
|
||||
|
||||
return gymBadges;
|
||||
}
|
||||
}
|
||||
|
|
@ -28,6 +28,9 @@ import entralinked.model.player.DreamItem;
|
|||
import entralinked.model.player.Player;
|
||||
import entralinked.model.player.PlayerManager;
|
||||
import entralinked.model.player.PlayerStatus;
|
||||
import entralinked.model.player.TrainerInfo;
|
||||
import entralinked.model.player.Offsets;
|
||||
import entralinked.model.player.TrainerInfoReader;
|
||||
import entralinked.model.user.ServiceSession;
|
||||
import entralinked.model.user.User;
|
||||
import entralinked.model.user.UserManager;
|
||||
|
|
@ -36,6 +39,7 @@ import entralinked.network.http.HttpRequestHandler;
|
|||
import entralinked.serialization.UrlEncodedFormFactory;
|
||||
import entralinked.serialization.UrlEncodedFormParser;
|
||||
import entralinked.utility.GsidUtility;
|
||||
import entralinked.utility.PointedInputStream;
|
||||
import entralinked.utility.LEOutputStream;
|
||||
import io.javalin.Javalin;
|
||||
import io.javalin.http.Context;
|
||||
|
|
@ -276,7 +280,7 @@ public class PglHandler implements HttpHandler {
|
|||
outputStream.writeShort(0x7E); // Just reset to default state
|
||||
outputStream.writeBytes(0, 24);
|
||||
}
|
||||
|
||||
|
||||
outputStream.writeShort(0); // ?
|
||||
|
||||
// Join Avenue visitor data -- copied in parts to 0x2422C in the save file.
|
||||
|
|
@ -321,13 +325,13 @@ public class PglHandler implements HttpHandler {
|
|||
*/
|
||||
private void handleMemoryLink(PglRequest request, Context ctx) throws IOException {
|
||||
LEOutputStream outputStream = new LEOutputStream(ctx.outputStream());
|
||||
|
||||
|
||||
// Check if Game Sync ID is valid
|
||||
if(!GsidUtility.isValidGameSyncId(request.gameSyncId())) {
|
||||
writeStatusCode(outputStream, 8); // Invalid Game Sync ID
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Player player = playerManager.getPlayer(request.gameSyncId());
|
||||
User user = ctx.attribute("user");
|
||||
|
||||
|
|
@ -419,7 +423,7 @@ public class PglHandler implements HttpHandler {
|
|||
private void handleUploadSaveData(PglRequest request, Context ctx) throws IOException {
|
||||
LEOutputStream outputStream = new LEOutputStream(ctx.outputStream());
|
||||
Player player = playerManager.getPlayer(request.gameSyncId());
|
||||
|
||||
|
||||
// Check if the player exists, has no Pokémon tucked in already and uses the same game version
|
||||
if(player == null
|
||||
|| (!configuration.allowOverwritingPlayerDreamInfo() && player.getStatus() != PlayerStatus.AWAKE)
|
||||
|
|
@ -446,17 +450,31 @@ public class PglHandler implements HttpHandler {
|
|||
}
|
||||
|
||||
// Read save data
|
||||
PkmnInfo dreamerInfo = null;
|
||||
TrainerInfo trainerInfo;
|
||||
PkmnInfo dreamerInfo;
|
||||
|
||||
try(FileInputStream inputStream = new FileInputStream(player.getSaveFile())) {
|
||||
inputStream.skip(0x1D300); // Skip to dream world data
|
||||
inputStream.skip(8); // Skip to Pokémon data
|
||||
try(PointedInputStream inputStream = new PointedInputStream(new FileInputStream(player.getSaveFile()))) {
|
||||
|
||||
inputStream.skipTo(Offsets.TRAINER_INFO);
|
||||
trainerInfo = TrainerInfoReader.readTrainerInfo(inputStream);
|
||||
|
||||
inputStream.skipTo(Offsets.DREAM_WORLD_INFO);
|
||||
inputStream.skip(Offsets.POKEMON_INFO_SUB_OFFSET);
|
||||
dreamerInfo = PkmnInfoReader.readPokeInfo(inputStream);
|
||||
|
||||
inputStream.skipTo(Offsets.ADVENTURE_START_TIME_OFFSET);
|
||||
inputStream.skip(Offsets.ADVENTURE_START_TIME_SUB_OFFSET);
|
||||
trainerInfo.setAdventureStartTime(TrainerInfoReader.readAdventureStartTime(inputStream));
|
||||
|
||||
inputStream.skipTo(Offsets.getMoneyAndBadges(request.gameVersion()));
|
||||
trainerInfo.setMoney(TrainerInfoReader.readLong(inputStream));
|
||||
trainerInfo.setGymBadges(TrainerInfoReader.readGymBadges(inputStream));
|
||||
}
|
||||
|
||||
|
||||
// Update and save player information
|
||||
player.setStatus(PlayerStatus.SLEEPING);
|
||||
player.setGameVersion(request.gameVersion());
|
||||
player.setTrainerInfo(trainerInfo);
|
||||
player.setDreamerInfo(dreamerInfo);
|
||||
|
||||
if(!playerManager.savePlayer(player)) {
|
||||
|
|
@ -523,7 +541,7 @@ public class PglHandler implements HttpHandler {
|
|||
writeStatusCode(outputStream, 8); // Invalid Game Sync ID
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Check if player doesn't exist already
|
||||
if(playerManager.doesPlayerExist(gameSyncId)) {
|
||||
writeStatusCode(outputStream, 2); // Duplicate Game Sync ID
|
||||
|
|
@ -548,7 +566,7 @@ public class PglHandler implements HttpHandler {
|
|||
outputStream.writeInt(status);
|
||||
outputStream.writeBytes(0, 124);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the index of the player's chosen DLC for the specified type and prepares DLC overriding if necessary.
|
||||
*/
|
||||
|
|
|
|||
46
src/main/java/entralinked/utility/PointedInputStream.java
Normal file
46
src/main/java/entralinked/utility/PointedInputStream.java
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
package entralinked.utility;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.FilterInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class PointedInputStream extends FilterInputStream {
|
||||
private long pointer = 0;
|
||||
|
||||
public PointedInputStream(InputStream inputStream) {
|
||||
super(inputStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
int read = super.read();
|
||||
if (read != -1) pointer += 1;
|
||||
return read;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(@NotNull byte[] b, int off, int len) throws IOException {
|
||||
int bytes = super.read(b, off, len);
|
||||
pointer += bytes;
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public long skipTo(long n) throws IOException {
|
||||
return skip(n - pointer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long skip(long n) throws IOException {
|
||||
long bytes = super.skip(n);
|
||||
pointer += bytes;
|
||||
return bytes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() throws IOException {
|
||||
pointer = 0;
|
||||
super.reset();
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user