Push everything to GitHub

Reformat code / Optimize imports

Rewrite blocks correctly. Cleanup and organize code.

Create a basic Entity tracker system. It works like shit, but hey. It is the start.

Release first version.
This commit is contained in:
Matsv 2016-07-18 21:02:46 +02:00
parent 296828649b
commit 92def58b81
25 changed files with 2197 additions and 0 deletions

17
.github/ISSUE_TEMPLATE.md vendored Normal file
View File

@ -0,0 +1,17 @@
##### What version of ViaBackwards are you using? Type /ver ViaBackwards:
##### What version of ViaVersion are you using? Type /ver ViaVersion:
##### What version of Spigot are you using? Type /ver:
##### What plugins are you using? Type /plugins:
##### How/when does this error happen? login?:
##### Is there an error in the console? Use pastebin.com. Is there a kick message?:

130
.gitignore vendored Normal file
View File

@ -0,0 +1,130 @@
# Created by .ignore support plugin (hsz.mobi)
### Maven template
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
dependency-reduced-pom.xml
buildNumber.properties
.mvn/timing.properties
### NetBeans template
nbproject/private/
build/
nbbuild/
dist/
nbdist/
nbactions.xml
.nb-gradle/
### Eclipse template
.metadata
bin/
tmp/
*.tmp
*.bak
*.swp
*~.nib
local.properties
.settings/
.loadpath
.recommenders
# Eclipse Core
.project
# External tool builders
.externalToolBuilders/
# Locally stored "Eclipse launch configurations"
*.launch
# PyDev specific (Python IDE for Eclipse)
*.pydevproject
# CDT-specific (C/C++ Development Tooling)
.cproject
# JDT-specific (Eclipse Java Development Tools)
.classpath
# Java annotation processor (APT)
.factorypath
# PDT-specific (PHP Development Tools)
.buildpath
# sbteclipse plugin
.target
# Tern plugin
.tern-project
# TeXlipse plugin
.texlipse
# STS (Spring Tool Suite)
.springBeans
# Code Recommenders
.recommenders/
### JetBrains template
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff:
.idea/workspace.xml
.idea/tasks.xml
.idea/dictionaries
.idea/vcs.xml
.idea/jsLibraryMappings.xml
# Sensitive or high-churn files:
.idea/dataSources.ids
.idea/dataSources.xml
.idea/dataSources.local.xml
.idea/sqlDataSources.xml
.idea/dynamic.xml
.idea/uiDesigner.xml
# Gradle:
.idea/gradle.xml
.idea/libraries
# Mongo Explorer plugin:
.idea/mongoSettings.xml
## File-based project format:
*.iws
## Plugin-specific files:
# IntelliJ
/out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
### Java template
*.class
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.ear
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*

13
README.md Normal file
View File

@ -0,0 +1,13 @@
# ViaBackwards
Allows 1.9.x on a 1.10 Spigot server.
Requires [ViaVersion](http://viaversion.com) to be installed
TODO:
- [ ] Cleanup code
- [ ] Improve the rewriters
- [ ] Make it possible to send metadata with the rewriteEntityId
- [ ] Add support for sound names
- [ ] Create JavaDocs
- [ ] Improve the Entity tracker system to work good with multiple versions.
- [ ] Make it possible to choose your own replacement blocks

106
pom.xml Normal file
View File

@ -0,0 +1,106 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~
~ Copyright (C) 2016 Matsv
~
~ This program is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ This program is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>nl.matsv</groupId>
<artifactId>viabackwards</artifactId>
<version>1.0</version>
<repositories>
<repository>
<id>spigot-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository>
<repository>
<id>viaversion-repo</id>
<url>https://repo.viaversion.com/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.10.2-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>us.myles</groupId>
<artifactId>viaversion</artifactId>
<version>0.9.8-SNAPSHOT</version>
</dependency>
<!-- Netty (Network Library) -->
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.0.20.Final</version>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.6</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<finalName>${project.name}-${project.version}</finalName>
<sourceDirectory>src/main/java</sourceDirectory>
<defaultGoal>clean install</defaultGoal>
<resources>
<resource>
<targetPath>.</targetPath>
<filtering>false</filtering>
<directory>.</directory>
<includes>
<include>LICENSE</include>
</includes>
</resource>
<resource>
<targetPath>.</targetPath>
<filtering>true</filtering>
<directory>src/main/resources/</directory>
<includes>
<include>*</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<showWarnings>false</showWarnings>
<showDeprecation>false</showDeprecation>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,35 @@
/*
*
* Copyright (C) 2016 Matsv
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package nl.matsv.viabackwards;
import nl.matsv.viabackwards.protocol.protocol1_9_4to1_10.Protocol1_9To1_10;
import org.bukkit.plugin.java.JavaPlugin;
import us.myles.ViaVersion.api.protocol.ProtocolRegistry;
import us.myles.ViaVersion.api.protocol.ProtocolVersion;
import java.util.Collections;
public class ViaBackwards extends JavaPlugin {
@Override
public void onEnable() {
// Register the protocol
ProtocolRegistry.registerProtocol(new Protocol1_9To1_10(), Collections.singletonList(ProtocolVersion.v1_9_3.getId()), ProtocolVersion.v1_10.getId());
}
}

View File

@ -0,0 +1,25 @@
/*
*
* Copyright (C) 2016 Matsv
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package nl.matsv.viabackwards.api;
import us.myles.ViaVersion.api.protocol.Protocol;
public abstract class BackwardsProtocol extends Protocol {
}

View File

@ -0,0 +1,26 @@
/*
*
* Copyright (C) 2016 Matsv
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package nl.matsv.viabackwards.api;
import nl.matsv.viabackwards.api.exceptions.RemovedValueException;
import us.myles.ViaVersion.api.minecraft.metadata.Metadata;
public interface MetaRewriter {
Metadata handleMetadata(boolean isObject, int entityType, Metadata data) throws RemovedValueException;
}

View File

@ -0,0 +1,24 @@
/*
*
* Copyright (C) 2016 Matsv
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package nl.matsv.viabackwards.api.exceptions;
import java.io.IOException;
public class RemovedValueException extends IOException {
}

View File

@ -0,0 +1,115 @@
/*
*
* Copyright (C) 2016 Matsv
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package nl.matsv.viabackwards.api.rewriters;
import nl.matsv.viabackwards.api.BackwardsProtocol;
import nl.matsv.viabackwards.utils.Block;
import nl.matsv.viabackwards.utils.ItemUtil;
import us.myles.ViaVersion.api.minecraft.item.Item;
import us.myles.viaversion.libs.opennbt.conversion.builtin.CompoundTagConverter;
import us.myles.viaversion.libs.opennbt.tag.builtin.*;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public abstract class BlockItemRewriter<T extends BackwardsProtocol> extends Rewriter<T> {
private static final CompoundTagConverter converter = new CompoundTagConverter();
private final Map<Short, Item> itemRewriter = new ConcurrentHashMap<>();
private final Map<Integer, Block> blockRewriter = new ConcurrentHashMap<>();
protected void rewriteItem(int oldItem, Item newItem) {
itemRewriter.put((short) oldItem, newItem);
}
protected void rewriteBlockItem(int oldId, Item newItem, Block newBlock) {
itemRewriter.put((short) oldId, newItem);
blockRewriter.put(oldId, newBlock);
}
protected Item handleItemToClient(Item item) {
if (item == null)
return null;
if (!itemRewriter.containsKey(item.getId()))
return item;
Item i = ItemUtil.copyItem(itemRewriter.get(item.getId()));
if (i.getTag() == null)
i.setTag(new CompoundTag(""));
i.getTag().put(createViaNBT(item));
if (item.getTag() != null)
for (Tag ai : item.getTag())
i.getTag().put(ai);
i.setAmount(item.getAmount());
return i;
}
protected Item handleItemToServer(Item item) {
if (item == null || item.getTag() == null)
return null;
CompoundTag tag = item.getTag();
if (tag.contains("ViaBackwards")) {
CompoundTag via = tag.get("ViaBackwards");
short id = (short) via.get("id").getValue();
short data = (short) via.get("data").getValue();
byte amount = (byte) via.get("amount").getValue();
CompoundTag extras = via.get("extras");
item.setId(id);
item.setData(data);
item.setAmount(amount);
item.setTag(converter.convert("", converter.convert(extras)));
// Remove data tag
tag.remove("ViaBackwards");
}
return item;
}
protected Block handleBlock(int block) {
if (!containsBlock(block))
return null;
return blockRewriter.get(block);
}
protected boolean containsBlock(int block) {
return blockRewriter.containsKey(block);
}
private CompoundTag createViaNBT(Item i) {
CompoundTag tag = new CompoundTag("ViaBackwards");
tag.put(new ShortTag("id", i.getId()));
tag.put(new ShortTag("data", i.getData()));
tag.put(new ByteTag("amount", i.getAmount()));
if (i.getTag() != null) {
tag.put(converter.convert("extras", converter.convert(i.getTag())));
} else
tag.put(new CompoundTag("extras"));
return tag;
}
protected CompoundTag getNamedTag(String text) {
CompoundTag tag = new CompoundTag("");
tag.put(new CompoundTag("display"));
((CompoundTag) tag.get("display")).put(new StringTag("Name", text));
return tag;
}
}

View File

@ -0,0 +1,115 @@
/*
*
* Copyright (C) 2016 Matsv
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package nl.matsv.viabackwards.api.rewriters;
import lombok.RequiredArgsConstructor;
import nl.matsv.viabackwards.api.BackwardsProtocol;
import nl.matsv.viabackwards.api.MetaRewriter;
import nl.matsv.viabackwards.api.exceptions.RemovedValueException;
import nl.matsv.viabackwards.api.storage.EntityTracker;
import nl.matsv.viabackwards.api.storage.EntityType;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.minecraft.metadata.Metadata;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
@RequiredArgsConstructor
public abstract class EntityRewriter<T extends BackwardsProtocol> extends Rewriter<T> {
private final Map<Short, Short> entityTypes = new ConcurrentHashMap<>();
private final Map<Short, Short> objectTypes = new ConcurrentHashMap<>();
private final List<MetaRewriter> metaRewriters = new ArrayList<>();
protected short getNewEntityType(UserConnection connection, int id) {
EntityType type = getEntityType(connection, id);
if (type.isObject()) {
return getNewObjectId(type.getEntityType());
} else {
return getNewEntityId(type.getEntityType());
}
}
protected EntityType getEntityType(UserConnection connection, int id) {
return connection.get(EntityTracker.class).getEntityType(id);
}
protected void addTrackedEntity(UserConnection connection, int entityId, boolean isObject, short typeId) {
connection.get(EntityTracker.class).trackEntityType(entityId, new EntityType(isObject, typeId));
}
protected void rewriteEntityId(int oldId, int newId) {
entityTypes.put((short) oldId, (short) newId);
}
protected boolean isRewriteEntityId(short id) {
return entityTypes.containsKey(id);
}
protected short getNewEntityId(short oldId) {
if (!isRewriteEntityId(oldId))
return oldId;
return entityTypes.get(oldId);
}
protected void rewriteObjectId(int oldId, int newId) {
objectTypes.put((short) oldId, (short) newId);
}
protected boolean isRewriteObjectId(short id) {
return objectTypes.containsKey(id);
}
protected short getNewObjectId(short oldId) {
if (!isRewriteObjectId(oldId))
return oldId;
return objectTypes.get(oldId);
}
public void registerMetaRewriter(MetaRewriter rewriter) {
metaRewriters.add(rewriter);
}
protected List<Metadata> handleMeta(UserConnection userConnection, int entityId, List<Metadata> metaData) {
EntityTracker tracker = userConnection.get(EntityTracker.class);
EntityType type = tracker.getEntityType(entityId);
List<Metadata> newMeta = new CopyOnWriteArrayList<>();
for (Metadata md : metaData) {
Metadata nmd = md;
try {
for (MetaRewriter rewriter : metaRewriters) {
if (type != null)
nmd = rewriter.handleMetadata(type.isObject(), type.getEntityType(), nmd);
else
nmd = rewriter.handleMetadata(false, -1, nmd);
if (nmd == null)
throw new RemovedValueException();
}
newMeta.add(nmd);
} catch (RemovedValueException ignored) {
}
}
return newMeta;
}
}

View File

@ -0,0 +1,44 @@
/*
*
* Copyright (C) 2016 Matsv
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package nl.matsv.viabackwards.api.rewriters;
import nl.matsv.viabackwards.api.BackwardsProtocol;
public abstract class Rewriter<T extends BackwardsProtocol> {
/**
* Register everything
*/
public void register(T protocol) {
registerPackets(protocol);
registerRewrites();
}
/**
* Register packet listeners
*
* @param protocol Protocol instance
*/
protected abstract void registerPackets(T protocol);
/**
* Register rewrites
*/
protected abstract void registerRewrites();
}

View File

@ -0,0 +1,59 @@
/*
*
* Copyright (C) 2016 Matsv
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package nl.matsv.viabackwards.api.rewriters;
import nl.matsv.viabackwards.api.BackwardsProtocol;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public abstract class SoundIdRewriter<T extends BackwardsProtocol> extends Rewriter<T> {
private Map<Integer, Integer> soundRewriter = new ConcurrentHashMap<>();
private Map<Integer, Float> pitchRewriter = new ConcurrentHashMap<>();
protected void rewriteSound(int newId, int oldId) {
soundRewriter.put(newId, oldId);
}
protected void rewriteSound(int newId, int oldId, float newPitch) {
rewriteSound(newId, oldId);
pitchRewriter.put(newId, newPitch);
}
public int handleSounds(int soundId) {
int newSoundId = soundId;
if (soundRewriter.containsKey(soundId))
newSoundId = soundId = soundRewriter.get(soundId);
for (Integer i : soundRewriter.keySet()) {
if (soundId > i)
newSoundId--;
}
return newSoundId;
}
public boolean hasPitch(int soundId) {
return pitchRewriter.containsKey(soundId);
}
public float handlePitch(int soundId) {
if (pitchRewriter.containsKey(soundId))
return pitchRewriter.get(soundId);
return -1;
}
}

View File

@ -0,0 +1,51 @@
/*
*
* Copyright (C) 2016 Matsv
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package nl.matsv.viabackwards.api.storage;
import us.myles.ViaVersion.api.data.StoredObject;
import us.myles.ViaVersion.api.data.UserConnection;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class EntityTracker extends StoredObject {
private Map<Integer, EntityType> entityMap = new ConcurrentHashMap<>();
public EntityTracker(UserConnection user) {
super(user);
}
public void trackEntityType(int id, EntityType type) {
if (entityMap.containsKey(id))
return;
entityMap.put(id, type);
}
public void removeEntity(int id) {
entityMap.remove(id);
}
public EntityType getEntityType(int id) {
return entityMap.get(id);
}
public boolean containsEntity(int id) {
return entityMap.containsKey(id);
}
}

View File

@ -0,0 +1,31 @@
/*
*
* Copyright (C) 2016 Matsv
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package nl.matsv.viabackwards.api.storage;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@AllArgsConstructor
@EqualsAndHashCode
public class EntityType {
private boolean object;
private short entityType;
}

View File

@ -0,0 +1,49 @@
/*
*
* Copyright (C) 2016 Matsv
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package nl.matsv.viabackwards.protocol.protocol1_9_4to1_10;
import lombok.Getter;
import nl.matsv.viabackwards.api.BackwardsProtocol;
import nl.matsv.viabackwards.api.storage.EntityTracker;
import nl.matsv.viabackwards.protocol.protocol1_9_4to1_10.packets.BlockItemPackets;
import nl.matsv.viabackwards.protocol.protocol1_9_4to1_10.packets.ChangedPackets;
import nl.matsv.viabackwards.protocol.protocol1_9_4to1_10.packets.EntityPackets;
import nl.matsv.viabackwards.protocol.protocol1_9_4to1_10.packets.SoundPackets;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
@Getter
public class Protocol1_9To1_10 extends BackwardsProtocol {
private EntityPackets entityPackets; // Required for the item rewriter
protected void registerPackets() {
new ChangedPackets().register(this);
new SoundPackets().register(this);
(entityPackets = new EntityPackets()).register(this);
new BlockItemPackets().register(this);
}
public void init(UserConnection user) {
user.put(new ClientWorld(user));
// Register EntityTracker if it doesn't exist yet.
if (!user.has(EntityTracker.class))
user.put(new EntityTracker(user));
}
}

View File

@ -0,0 +1,43 @@
/*
*
* Copyright (C) 2016 Matsv
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package nl.matsv.viabackwards.protocol.protocol1_9_4to1_10.chunks;
import lombok.AllArgsConstructor;
import lombok.Data;
import us.myles.ViaVersion.api.minecraft.chunks.Chunk;
import us.myles.viaversion.libs.opennbt.tag.builtin.CompoundTag;
import java.util.List;
@Data
@AllArgsConstructor
public class Chunk1_10 implements Chunk {
private int x;
private int z;
private boolean groundUp;
private int bitmask;
private ChunkSection1_10[] sections;
private byte[] biomeData;
List<CompoundTag> blockEntities;
@Override
public boolean isBiomeData() {
return biomeData != null;
}
}

View File

@ -0,0 +1,122 @@
/*
*
* Copyright (C) 2016 Matsv
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package nl.matsv.viabackwards.protocol.protocol1_9_4to1_10.chunks;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import org.bukkit.World;
import us.myles.ViaVersion.api.minecraft.chunks.Chunk;
import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection;
import us.myles.ViaVersion.api.type.PartialType;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.api.type.types.minecraft.BaseChunkType;
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
import us.myles.viaversion.libs.opennbt.tag.builtin.CompoundTag;
import java.util.Arrays;
import java.util.BitSet;
import java.util.List;
public class Chunk1_10Type extends PartialType<Chunk, ClientWorld> {
public Chunk1_10Type(ClientWorld param) {
super(param, Chunk.class);
}
@Override
public Chunk read(ByteBuf input, ClientWorld world) throws Exception {
int chunkX = input.readInt();
int chunkZ = input.readInt();
boolean groundUp = input.readBoolean();
int primaryBitmask = Type.VAR_INT.read(input);
int size = Type.VAR_INT.read(input);
BitSet usedSections = new BitSet(16);
ChunkSection1_10[] sections = new ChunkSection1_10[16];
// Calculate section count from bitmask
for (int i = 0; i < 16; i++) {
if ((primaryBitmask & (1 << i)) != 0) {
usedSections.set(i);
}
}
// Read sections
for (int i = 0; i < 16; i++) {
if (!usedSections.get(i)) continue; // Section not set
ChunkSection1_10 section = new ChunkSection1_10();
sections[i] = section;
section.readBlocks(input);
section.readBlockLight(input);
if (world.getEnvironment() == World.Environment.NORMAL) {
section.readSkyLight(input);
}
}
byte[] biomeData = groundUp ? new byte[256] : null;
if (groundUp) {
input.readBytes(biomeData);
}
List<CompoundTag> nbtData = Arrays.asList(Type.NBT_ARRAY.read(input));
return new Chunk1_10(chunkX, chunkZ, groundUp, primaryBitmask, sections, biomeData, nbtData);
}
@Override
public void write(ByteBuf output, ClientWorld world, Chunk input) throws Exception {
if (!(input instanceof Chunk1_10))
throw new Exception("Tried to send the wrong chunk type from 1.9.3-4 chunk: " + input.getClass());
Chunk1_10 chunk = (Chunk1_10) input;
output.writeInt(chunk.getX());
output.writeInt(chunk.getZ());
output.writeBoolean(chunk.isGroundUp());
Type.VAR_INT.write(output, chunk.getBitmask());
ByteBuf buf = Unpooled.buffer();
for (int i = 0; i < 16; i++) {
ChunkSection section = chunk.getSections()[i];
if (section == null) continue; // Section not set
section.writeBlocks(buf);
section.writeBlockLight(buf);
if (!section.hasSkyLight()) continue; // No sky light, we're done here.
section.writeSkyLight(buf);
}
buf.readerIndex(0);
Type.VAR_INT.write(output, buf.readableBytes() + (chunk.isBiomeData() ? 256 : 0));
output.writeBytes(buf);
buf.release(); // release buffer
// Write biome data
if (chunk.isBiomeData()) {
output.writeBytes(chunk.getBiomeData());
}
Type.NBT_ARRAY.write(output, chunk.getBlockEntities().toArray(new CompoundTag[0]));
}
@Override
public Class<? extends Type> getBaseClass() {
return BaseChunkType.class;
}
}

View File

@ -0,0 +1,314 @@
/*
*
* Copyright (C) 2016 Matsv
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package nl.matsv.viabackwards.protocol.protocol1_9_4to1_10.chunks;
import com.google.common.collect.Lists;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import lombok.Getter;
import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection;
import us.myles.ViaVersion.api.minecraft.chunks.NibbleArray;
import us.myles.ViaVersion.api.type.Type;
import java.util.List;
/**
* From the ViaVersion code {@link us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.chunks.ChunkSection1_9_1_2}
*/
public class ChunkSection1_10 implements ChunkSection {
/**
* Size (dimensions) of blocks in a chunks section.
*/
public static final int SIZE = 16 * 16 * 16; // width * depth * height
/**
* Length of the sky and block light nibble arrays.
*/
public static final int LIGHT_LENGTH = 16 * 16 * 16 / 2; // size * size * size / 2 (nibble bit count)
/**
* Length of the block data array.
*/
@Getter
private final List<Integer> palette = Lists.newArrayList();
private final int[] blocks;
private final NibbleArray blockLight;
private NibbleArray skyLight;
public ChunkSection1_10() {
this.blocks = new int[SIZE];
this.blockLight = new NibbleArray(SIZE);
palette.add(0); // AIR
}
/**
* Set a block in the chunks
*
* @param x Block X
* @param y Block Y
* @param z Block Z
* @param type The type of the block
* @param data The data value of the block
*/
public void setBlock(int x, int y, int z, int type, int data) {
setBlock(index(x, y, z), type, data);
}
public int getBlockId(int x, int y, int z) {
int index = blocks[index(x, y, z)];
return palette.get(index) >> 4;
}
/**
* Set a block in the chunks based on the index
*
* @param idx Index
* @param type The type of the block
* @param data The data value of the block
*/
public void setBlock(int idx, int type, int data) {
int hash = type << 4 | (data & 0xF);
int index = palette.indexOf(hash);
if (index == -1) {
index = palette.size();
palette.add(hash);
}
blocks[idx] = index;
}
/**
* Set the block light array
*
* @param data The value to set the block light to
*/
public void setBlockLight(byte[] data) {
blockLight.setHandle(data);
}
/**
* Set the sky light array
*
* @param data The value to set the sky light to
*/
public void setSkyLight(byte[] data) {
if (data.length != LIGHT_LENGTH) throw new IllegalArgumentException("Data length != " + LIGHT_LENGTH);
this.skyLight = new NibbleArray(data);
}
private int index(int x, int y, int z) {
return y << 8 | z << 4 | x;
}
/**
* Read blocks from input stream.
* This reads all the block related data:
* <ul>
* <li>Block length/palette type</li>
* <li>Palette</li>
* <li>Block hashes/palette reference</li>
* </ul>
*
* @param input The buffer to read from.
* @throws Exception
*/
public void readBlocks(ByteBuf input) throws Exception {
palette.clear();
// Reaad bits per block
int bitsPerBlock = input.readUnsignedByte();
long maxEntryValue = (1L << bitsPerBlock) - 1;
if (bitsPerBlock == 0) {
bitsPerBlock = 13;
}
if (bitsPerBlock < 4) {
bitsPerBlock = 4;
}
if (bitsPerBlock > 8) {
bitsPerBlock = 13;
}
int paletteLength = Type.VAR_INT.read(input);
// Read palette
for (int i = 0; i < paletteLength; i++) {
if (bitsPerBlock != 13) {
palette.add(Type.VAR_INT.read(input));
} else {
Type.VAR_INT.read(input);
}
}
// Read blocks
Long[] blockData = Type.LONG_ARRAY.read(input);
if (blockData.length > 0) {
for (int i = 0; i < blocks.length; i++) {
int bitIndex = i * bitsPerBlock;
int startIndex = bitIndex / 64;
int endIndex = ((i + 1) * bitsPerBlock - 1) / 64;
int startBitSubIndex = bitIndex % 64;
int val;
if (startIndex == endIndex) {
val = (int) (blockData[startIndex] >>> startBitSubIndex & maxEntryValue);
} else {
int endBitSubIndex = 64 - startBitSubIndex;
val = (int) ((blockData[startIndex] >>> startBitSubIndex | blockData[endIndex] << endBitSubIndex) & maxEntryValue);
}
if (bitsPerBlock == 13) {
int type = val >> 4;
int data = val & 0xF;
setBlock(i, type, data);
} else {
blocks[i] = val;
}
}
}
}
/**
* Read block light from buffer.
*
* @param input The buffer to read from
*/
public void readBlockLight(ByteBuf input) {
byte[] handle = new byte[LIGHT_LENGTH];
input.readBytes(handle);
blockLight.setHandle(handle);
}
/**
* Read sky light from buffer.
* Note: Only sent in overworld!
*
* @param input The buffer to read from
*/
public void readSkyLight(ByteBuf input) {
byte[] handle = new byte[LIGHT_LENGTH];
input.readBytes(handle);
if (skyLight != null) {
skyLight.setHandle(handle);
return;
}
this.skyLight = new NibbleArray(handle);
}
/**
* Write the blocks to a buffer.
*
* @param output The buffer to write to.
* @throws Exception Throws if it failed to write.
*/
public void writeBlocks(ByteBuf output) throws Exception {
// Write bits per block
int bitsPerBlock = 4;
while (palette.size() > 1 << bitsPerBlock) {
bitsPerBlock += 1;
}
long maxEntryValue = (1L << bitsPerBlock) - 1;
output.writeByte(bitsPerBlock);
// Write pallet (or not)
Type.VAR_INT.write(output, palette.size());
for (int mappedId : palette) {
Type.VAR_INT.write(output, mappedId);
}
int length = (int) Math.ceil(SIZE * bitsPerBlock / 64.0);
Type.VAR_INT.write(output, length);
long[] data = new long[length];
for (int index = 0; index < blocks.length; index++) {
int value = blocks[index];
int bitIndex = index * bitsPerBlock;
int startIndex = bitIndex / 64;
int endIndex = ((index + 1) * bitsPerBlock - 1) / 64;
int startBitSubIndex = bitIndex % 64;
data[startIndex] = data[startIndex] & ~(maxEntryValue << startBitSubIndex) | ((long) value & maxEntryValue) << startBitSubIndex;
if (startIndex != endIndex) {
int endBitSubIndex = 64 - startBitSubIndex;
data[endIndex] = data[endIndex] >>> endBitSubIndex << endBitSubIndex | ((long) value & maxEntryValue) >> endBitSubIndex;
}
}
for (long l : data) {
Type.LONG.write(output, l);
}
}
/**
* Write the block light to a buffer
*
* @param output The buffer to write to
*/
public void writeBlockLight(ByteBuf output) {
output.writeBytes(blockLight.getHandle());
}
/**
* Write the sky light to a buffer
*
* @param output The buffer to write to
*/
public void writeSkyLight(ByteBuf output) {
output.writeBytes(skyLight.getHandle());
}
/**
* Check if sky light is present
*
* @return True if skylight is present
*/
public boolean hasSkyLight() {
return skyLight != null;
}
/**
* Get expected size of this chunks section.
*
* @return Amount of bytes sent by this section
* @throws Exception If it failed to calculate bits properly
*/
public int getExpectedSize() throws Exception {
int bitsPerBlock = palette.size() > 255 ? 16 : 8;
int bytes = 1; // bits per block
bytes += paletteBytes(); // palette
bytes += countBytes(bitsPerBlock == 16 ? SIZE * 2 : SIZE); // block data length
bytes += (palette.size() > 255 ? 2 : 1) * SIZE; // block data
bytes += LIGHT_LENGTH; // block light
bytes += hasSkyLight() ? LIGHT_LENGTH : 0; // sky light
return bytes;
}
private int paletteBytes() throws Exception {
// Count bytes used by pallet
int bytes = countBytes(palette.size());
for (int mappedId : palette) {
bytes += countBytes(mappedId);
}
return bytes;
}
private int countBytes(int value) throws Exception {
// Count amount of bytes that would be sent if the value were sent as a VarInt
ByteBuf buf = Unpooled.buffer();
Type.VAR_INT.write(buf, value);
buf.readerIndex(0);
int bitCount = buf.readableBytes();
buf.release();
return bitCount;
}
}

View File

@ -0,0 +1,289 @@
/*
*
* Copyright (C) 2016 Matsv
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package nl.matsv.viabackwards.protocol.protocol1_9_4to1_10.packets;
import nl.matsv.viabackwards.api.rewriters.BlockItemRewriter;
import nl.matsv.viabackwards.protocol.protocol1_9_4to1_10.Protocol1_9To1_10;
import nl.matsv.viabackwards.protocol.protocol1_9_4to1_10.chunks.Chunk1_10;
import nl.matsv.viabackwards.protocol.protocol1_9_4to1_10.chunks.Chunk1_10Type;
import nl.matsv.viabackwards.protocol.protocol1_9_4to1_10.chunks.ChunkSection1_10;
import nl.matsv.viabackwards.utils.Block;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.minecraft.item.Item;
import us.myles.ViaVersion.api.remapper.PacketHandler;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.packets.State;
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
// TODO REWRITE PLUGINS MESSAGE ITEMS
public class BlockItemPackets extends BlockItemRewriter<Protocol1_9To1_10> {
protected void registerPackets(Protocol1_9To1_10 protocol) {
/* Item packets */
// Set slot packet
protocol.registerOutgoing(State.PLAY, 0x16, 0x16, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.BYTE); // 0 - Window ID
map(Type.SHORT); // 1 - Slot ID
map(Type.ITEM); // 2 - Slot Value
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
Item stack = wrapper.get(Type.ITEM, 0);
wrapper.set(Type.ITEM, 0, handleItemToClient(stack));
}
});
}
});
// Window items packet
protocol.registerOutgoing(State.PLAY, 0x14, 0x14, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.UNSIGNED_BYTE); // 0 - Window ID
map(Type.ITEM_ARRAY); // 1 - Window Values
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
Item[] stacks = wrapper.get(Type.ITEM_ARRAY, 0);
for (int i = 0; i < stacks.length; i++)
stacks[i] = handleItemToClient(stacks[i]);
}
});
}
});
// Entity Equipment Packet
protocol.registerOutgoing(State.PLAY, 0x3C, 0x3C, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity ID
map(Type.VAR_INT); // 1 - Slot ID
map(Type.ITEM); // 2 - Item
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
Item stack = wrapper.get(Type.ITEM, 0);
wrapper.set(Type.ITEM, 0, handleItemToClient(stack));
}
});
}
});
// Plugin message Packet -> Trading
protocol.registerOutgoing(State.PLAY, 0x18, 0x18, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.STRING); // 0 - Channel
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
if (wrapper.get(Type.STRING, 0).equalsIgnoreCase("MC|TrList")) {
wrapper.passthrough(Type.INT); // Passthrough Window ID
int size = wrapper.passthrough(Type.BYTE);
for (int i = 0; i < size; i++) {
wrapper.write(Type.ITEM, handleItemToClient(wrapper.read(Type.ITEM))); // Input Item
wrapper.write(Type.ITEM, handleItemToClient(wrapper.read(Type.ITEM))); // Output Item
boolean secondItem = wrapper.passthrough(Type.BOOLEAN); // Has second item
if (secondItem)
wrapper.write(Type.ITEM, handleItemToClient(wrapper.read(Type.ITEM))); // Second Item
wrapper.passthrough(Type.BOOLEAN); // Trade disabled
wrapper.passthrough(Type.INT); // Number of tools uses
wrapper.passthrough(Type.INT); // Maximum number of trade uses
}
}
}
});
}
});
// Click window packet
protocol.registerIncoming(State.PLAY, 0x07, 0x07, new
PacketRemapper() {
@Override
public void registerMap() {
map(Type.UNSIGNED_BYTE); // 0 - Window ID
map(Type.SHORT); // 1 - Slot
map(Type.BYTE); // 2 - Button
map(Type.SHORT); // 3 - Action number
map(Type.VAR_INT); // 4 - Mode
map(Type.ITEM); // 5 - Clicked Item
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
Item item = wrapper.get(Type.ITEM, 0);
handleItemToServer(item);
}
});
}
}
);
// Creative Inventory Action
protocol.registerIncoming(State.PLAY, 0x18, 0x18, new
PacketRemapper() {
@Override
public void registerMap() {
map(Type.SHORT); // 0 - Slot
map(Type.ITEM); // 1 - Clicked Item
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
Item item = wrapper.get(Type.ITEM, 0);
handleItemToServer(item);
}
});
}
}
);
/* Block packets */
// Chunk packet
protocol.registerOutgoing(State.PLAY, 0x20, 0x20, new
PacketRemapper() {
@Override
public void registerMap() {
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
ClientWorld clientWorld = wrapper.user().get(ClientWorld.class);
Chunk1_10Type type = new Chunk1_10Type(clientWorld);
Chunk1_10 chunk = (Chunk1_10) wrapper.passthrough(type);
for (int i = 0; i < chunk.getSections().length; i++) {
ChunkSection1_10 section = chunk.getSections()[i];
if (section == null)
continue;
for (int x = 0; x < 16; x++) {
for (int y = 0; y < 16; y++) {
for (int z = 0; z < 16; z++) {
int block = section.getBlockId(x, y, z);
if (containsBlock(block)) {
Block b = handleBlock(block);
section.setBlock(x, y, z, b.getId(), b.getData());
}
}
}
}
}
}
});
}
}
);
// Block Change Packet
protocol.registerOutgoing(State.PLAY, 0x0B, 0x0B, new
PacketRemapper() {
@Override
public void registerMap() {
map(Type.POSITION); // 0 - Block Position
map(Type.VAR_INT); // 1 - Block
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int idx = wrapper.get(Type.VAR_INT, 0);
wrapper.set(Type.VAR_INT, 0, handleBlockID(idx));
}
});
}
}
);
// Multi Block Change Packet
protocol.registerOutgoing(State.PLAY, 0x10, 0x10, new
PacketRemapper() {
@Override
public void registerMap() {
map(Type.INT); // 0 - Chunk X
map(Type.INT); // 1 - Chunk Z
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int count = wrapper.passthrough(Type.VAR_INT); // Array length
for (int i = 0; i < count; i++) {
wrapper.passthrough(Type.UNSIGNED_BYTE); // Horizontal position
wrapper.passthrough(Type.UNSIGNED_BYTE); // Y coords
int id = wrapper.read(Type.VAR_INT); // Block ID
wrapper.write(Type.VAR_INT, handleBlockID(id));
}
}
});
}
}
);
/* Register Metadata */
protocol.getEntityPackets().registerMetaRewriter((isObject, entityType, data) -> {
if (data.getTypeID() == 5) // Is Item
data.setValue(handleItemToClient((Item) data.getValue()));
return data;
});
}
protected int handleBlockID(int idx) {
int type = idx >> 4;
if (!containsBlock(type))
return idx;
Block b = handleBlock(type);
return (b.getId() << 4 | (b.getData() & 15));
}
@Override
protected void registerRewrites() {
rewriteItem(255, new Item((short) 166, (byte) 1, (short) 0, getNamedTag("1.10 Structure Block"))); // Structure block only item since the structure block is in 1.9
rewriteBlockItem(217, new Item((short) 287, (byte) 1, (short) 0, getNamedTag("1.10 Structure Void")), new Block(287, 0)); // Structure void to string
rewriteBlockItem(213, new Item((short) 159, (byte) 1, (short) 1, getNamedTag("1.10 Magma Block")), new Block(159, 1)); // Magma block to orange clay
rewriteBlockItem(214, new Item((short) 159, (byte) 1, (short) 14, getNamedTag("1.10 Nether Ward Block")), new Block(159, 14)); // Nether wart block to red clay
rewriteBlockItem(215, new Item((short) 112, (byte) 1, (short) 0, getNamedTag("1.10 Red Nether Bricks")), new Block(112, 0)); // Red nether brick to nether brick
rewriteBlockItem(216, new Item((short) 155, (byte) 1, (short) 0, getNamedTag("1.10 Bone Block")), new Block(155, 0)); // Bone block to quartz
}
}

View File

@ -0,0 +1,40 @@
/*
*
* Copyright (C) 2016 Matsv
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package nl.matsv.viabackwards.protocol.protocol1_9_4to1_10.packets;
import nl.matsv.viabackwards.api.BackwardsProtocol;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.packets.State;
public class ChangedPackets {
public void register(BackwardsProtocol protocol) {
/* ServerBound packets */
// ResourcePack status
protocol.registerIncoming(State.PLAY, 0x16, 0x16, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.STRING, Type.NOTHING); // 0 - Hash
map(Type.VAR_INT); // 1 - Result
}
});
}
}

View File

@ -0,0 +1,366 @@
/*
*
* Copyright (C) 2016 Matsv
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package nl.matsv.viabackwards.protocol.protocol1_9_4to1_10.packets;
import nl.matsv.viabackwards.api.exceptions.RemovedValueException;
import nl.matsv.viabackwards.api.rewriters.EntityRewriter;
import nl.matsv.viabackwards.api.storage.EntityTracker;
import nl.matsv.viabackwards.protocol.protocol1_9_4to1_10.Protocol1_9To1_10;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.remapper.PacketHandler;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.api.type.types.version.Types1_9;
import us.myles.ViaVersion.packets.State;
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.metadata.NewType;
public class EntityPackets extends EntityRewriter<Protocol1_9To1_10> {
@Override
protected void registerPackets(Protocol1_9To1_10 protocol) {
// Spawn Object
protocol.registerOutgoing(State.PLAY, 0x00, 0x00, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity id
map(Type.UUID); // 1 - UUID
map(Type.BYTE); // 2 - Type
// Track Entity
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
addTrackedEntity(
wrapper.user(),
wrapper.get(Type.VAR_INT, 0),
true,
wrapper.get(Type.BYTE, 0)
);
}
});
}
});
// Spawn Experience Orb
protocol.registerOutgoing(State.PLAY, 0x01, 0x01, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity id
// Track entity
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
addTrackedEntity(
wrapper.user(),
wrapper.get(Type.VAR_INT, 0),
true,
(short) 2
);
}
});
}
});
// Spawn Global Entity
protocol.registerOutgoing(State.PLAY, 0x02, 0x02, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity ID
map(Type.BYTE); // 1 - Type
// Track entity
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
addTrackedEntity(
wrapper.user(),
wrapper.get(Type.VAR_INT, 0),
true,
wrapper.get(Type.BYTE, 0)
);
}
});
}
});
// Spawn Mob
protocol.registerOutgoing(State.PLAY, 0x03, 0x03, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity id
map(Type.UUID); // 1 - UUID
map(Type.UNSIGNED_BYTE); // 2 - Entity Type
map(Type.DOUBLE); // 3 - X
map(Type.DOUBLE); // 4 - Y
map(Type.DOUBLE); // 5 - Z
map(Type.BYTE); // 6 - Yaw
map(Type.BYTE); // 7 - Pitch
map(Type.BYTE); // 8 - Head Pitch
map(Type.SHORT); // 9 - Velocity X
map(Type.SHORT); // 10 - Velocity Y
map(Type.SHORT); // 11 - Velocity Z
map(Types1_9.METADATA_LIST); // 12 - Metadata
// Track entity
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
addTrackedEntity(
wrapper.user(),
wrapper.get(Type.VAR_INT, 0),
false,
wrapper.get(Type.UNSIGNED_BYTE, 0)
);
}
});
// Rewrite entity ids
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
wrapper.set(Type.UNSIGNED_BYTE, 0,
getNewEntityType(
wrapper.user(),
wrapper.get(Type.VAR_INT, 0)
));
}
});
// Rewrite metadata
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
wrapper.set(
Types1_9.METADATA_LIST,
0,
handleMeta(
wrapper.user(),
wrapper.get(Type.VAR_INT, 0),
wrapper.get(Types1_9.METADATA_LIST, 0)
)
);
}
});
}
});
// Spawn Painting
protocol.registerOutgoing(State.PLAY, 0x04, 0x04, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity ID
// Track entity
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
addTrackedEntity(
wrapper.user(),
wrapper.get(Type.VAR_INT, 0),
true,
(short) 9
);
}
});
}
});
// Join game
protocol.registerOutgoing(State.PLAY, 0x23, 0x23, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.INT); // 0 - Entity ID
map(Type.UNSIGNED_BYTE); // 1 - Gamemode
map(Type.INT); // 2 - Dimension
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
addTrackedEntity(
wrapper.user(),
wrapper.get(Type.INT, 0),
false,
(short) -12
);
}
});
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
ClientWorld clientWorld = wrapper.user().get(ClientWorld.class);
int dimensionId = wrapper.get(Type.INT, 1);
clientWorld.setEnvironment(dimensionId);
}
});
}
});
// Respawn Packet (save dimension id)
protocol.registerOutgoing(State.PLAY, 0x33, 0x33, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.INT); // 0 - Dimension ID
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
ClientWorld clientWorld = wrapper.user().get(ClientWorld.class);
int dimensionId = wrapper.get(Type.INT, 0);
clientWorld.setEnvironment(dimensionId);
}
});
}
});
// Spawn Player
protocol.registerOutgoing(State.PLAY, 0x05, 0x05, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity ID
map(Type.UUID); // 1 - Player UUID
map(Type.DOUBLE); // 2 - X
map(Type.DOUBLE); // 3 - Y
map(Type.DOUBLE); // 4 - Z
map(Type.BYTE); // 5 - Yaw
map(Type.BYTE); // 6 - Pitch
map(Types1_9.METADATA_LIST); // 7 - Metadata list
// Track Entity
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
addTrackedEntity(
wrapper.user(),
wrapper.get(Type.VAR_INT, 0),
false,
(short) -12
);
}
});
// Rewrite Metadata
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
wrapper.set(
Types1_9.METADATA_LIST,
0,
handleMeta(
wrapper.user(),
wrapper.get(Type.VAR_INT, 0),
wrapper.get(Types1_9.METADATA_LIST, 0)
)
);
}
});
}
});
// Destroy entities
protocol.registerOutgoing(State.PLAY, 0x30, 0x30, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT_ARRAY); // 0 - Entity IDS
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
for (int entity : wrapper.get(Type.VAR_INT_ARRAY, 0))
wrapper.user().get(EntityTracker.class).removeEntity(entity);
}
});
}
});
// Metadata packet
protocol.registerOutgoing(State.PLAY, 0x39, 0x39, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity ID
map(Types1_9.METADATA_LIST); // 1 - Metadata list
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
wrapper.set(
Types1_9.METADATA_LIST,
0,
handleMeta(
wrapper.user(),
wrapper.get(Type.VAR_INT, 0),
wrapper.get(Types1_9.METADATA_LIST, 0)
)
);
}
});
}
});
}
@Override
protected void registerRewrites() {
rewriteEntityId(102, 91); // Replace polar bear with sheep
registerMetaRewriter((isObject, entityType, data) -> { // Change the sheep color when the polar bear is stending up
if (!isObject && entityType != 102)
return data;
if (data.getId() == 13) { // is boolean
boolean b = (boolean) data.getValue();
data.setId(13);
data.setType(Type.BYTE);
data.setTypeID(NewType.Byte.getTypeID());
data.setValue(b ? (byte) (14 & 0x0F) : 0);
}
return data;
});
registerMetaRewriter((isObject, entityType, data) -> { // Change husk to normal zombie
if (isObject || entityType != 54)
return data;
if (data.getId() == 13 && data.getTypeID() == 1 && (int) data.getValue() == 6)
data.setValue(0);
return data;
});
registerMetaRewriter((isObject, entityType, data) -> { // Change stray- to normal skeleton
if (isObject || entityType != 51)
return data;
if (data.getId() == 12 && data.getTypeID() == 1 && (int) data.getValue() == 2)
data.setValue(0);
return data;
});
registerMetaRewriter((isObject, entityType, m) -> {
if (m.getId() == 5)
throw new RemovedValueException();
else if (m.getId() >= 5)
m.setId(m.getId() - 1);
return m;
});
}
}

View File

@ -0,0 +1,113 @@
/*
*
* Copyright (C) 2016 Matsv
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package nl.matsv.viabackwards.protocol.protocol1_9_4to1_10.packets;
import nl.matsv.viabackwards.api.rewriters.SoundIdRewriter;
import nl.matsv.viabackwards.protocol.protocol1_9_4to1_10.Protocol1_9To1_10;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.remapper.PacketHandler;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.remapper.ValueTransformer;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.packets.State;
public class SoundPackets extends SoundIdRewriter<Protocol1_9To1_10> {
protected static ValueTransformer<Float, Short> toOldPitch = new ValueTransformer<Float, Short>(Type.UNSIGNED_BYTE) {
public Short transform(PacketWrapper packetWrapper, Float inputValue) throws Exception {
return (short) Math.round(inputValue * 63.5F);
}
};
@Override
protected void registerPackets(Protocol1_9To1_10 protocol) {
// Named sound effect
protocol.registerOutgoing(State.PLAY, 0x19, 0x19, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.STRING); // 0 - Sound name
map(Type.VAR_INT); // 1 - Sound Category
map(Type.INT); // 2 - x
map(Type.INT); // 3 - y
map(Type.INT); // 4 - z
map(Type.FLOAT); // 5 - Volume
map(Type.FLOAT, toOldPitch); // 6 - Pitch
}
});
// Sound effect
protocol.registerOutgoing(State.PLAY, 0x46, 0x46, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Sound name
map(Type.VAR_INT); // 1 - Sound Category
map(Type.INT); // 2 - x
map(Type.INT); // 3 - y
map(Type.INT); // 4 - z
map(Type.FLOAT); // 5 - Volume
map(Type.FLOAT, toOldPitch); // 6 - Pitch
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int oldId = wrapper.get(Type.VAR_INT, 0);
int newId = handleSounds(oldId);
if (newId == -1)
wrapper.cancel();
else {
if (hasPitch(oldId))
wrapper.set(Type.UNSIGNED_BYTE, 0, (short) Math.round(handlePitch(oldId) * 63.5F));
wrapper.set(Type.VAR_INT, 0, newId);
}
}
});
}
});
}
@Override
protected void registerRewrites() {
rewriteSound(24, -1); // Enchantment table sound
// Husk
rewriteSound(249, 400); // Husk -> Zombie ambient
rewriteSound(250, 404); // Husk -> Zombie death
rewriteSound(251, 405); // Husk -> Zombie hurt
rewriteSound(252, 407); // Husk -> Zombie step
// Polar bear
rewriteSound(301, 400, .6F); // Polar bear ambient
rewriteSound(302, 400, 1.9F); // Polar baby bear ambient
rewriteSound(303, 404, .7F); // Polar bear death
rewriteSound(304, 320, .6F); // Polar bear hurt
rewriteSound(305, 241, .6F); // Polar bear step
rewriteSound(306, 393, 1.2F); // Polar bear warning
// Stray
rewriteSound(365, 331); // Stray -> Skeleton ambient
rewriteSound(366, 332); // Stray -> Skeleton death
rewriteSound(367, 333); // Stray -> Skeleton hurt
rewriteSound(368, 335); // Stray -> Skeleton step
// Wither skeleton
rewriteSound(387, 331); // Wither skeleton -> Skeleton ambient
rewriteSound(388, 332); // Wither skeleton -> Skeleton death
rewriteSound(389, 333); // Wither skeleton -> Skeleton hurt
rewriteSound(390, 335); // Wither skeleton -> Skeleton step
}
}

View File

@ -0,0 +1,31 @@
/*
*
* Copyright (C) 2016 Matsv
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package nl.matsv.viabackwards.utils;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
@AllArgsConstructor
@EqualsAndHashCode
@Data
public class Block {
private int id;
private int data;
}

View File

@ -0,0 +1,29 @@
/*
*
* Copyright (C) 2016 Matsv
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package nl.matsv.viabackwards.utils;
import us.myles.ViaVersion.api.minecraft.item.Item;
public class ItemUtil {
public static Item copyItem(Item item) {
if (item == null) return null;
return new Item(item.getId(), item.getAmount(), item.getData(), item.getTag() != null ? item.getTag().clone() : null);
}
}

View File

@ -0,0 +1,10 @@
name: ViaBackwards
version: ${project.version}
main: nl.matsv.viabackwards.ViaBackwards
description: Allow
authors: [Matsv]
website: https://matsv.nl
load: STARTUP
depend: [ViaVersion]