Skip to content

Instantly share code, notes, and snippets.

@BeYkeRYkt
Last active March 13, 2018 11:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save BeYkeRYkt/8769428d40594116b9cbd6ecf4e8c496 to your computer and use it in GitHub Desktop.
Save BeYkeRYkt/8769428d40594116b9cbd6ecf4e8c496 to your computer and use it in GitHub Desktop.
"FastConnect" analog for "world2world"
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 Vladimir Mikhailov
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package ru.beykerykt.bukkit.fastdimension;
import java.util.Iterator;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.WeatherType;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_11_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_11_R1.entity.CraftPlayer;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.event.player.PlayerChangedWorldEvent;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import net.minecraft.server.v1_11_R1.BlockPosition;
import net.minecraft.server.v1_11_R1.EntityPlayer;
import net.minecraft.server.v1_11_R1.MobEffect;
import net.minecraft.server.v1_11_R1.PacketPlayOutEntityDestroy;
import net.minecraft.server.v1_11_R1.PacketPlayOutEntityEffect;
import net.minecraft.server.v1_11_R1.PacketPlayOutExperience;
import net.minecraft.server.v1_11_R1.PacketPlayOutHeldItemSlot;
import net.minecraft.server.v1_11_R1.PacketPlayOutRespawn;
import net.minecraft.server.v1_11_R1.PacketPlayOutSpawnPosition;
import net.minecraft.server.v1_11_R1.PacketPlayOutUnloadChunk;
import net.minecraft.server.v1_11_R1.PacketPlayOutUpdateTime;
import net.minecraft.server.v1_11_R1.PacketPlayOutWorldBorder;
import net.minecraft.server.v1_11_R1.WorldBorder;
import net.minecraft.server.v1_11_R1.WorldServer;
public class FastDimension extends JavaPlugin implements Listener {
@Override
public void onEnable() {
getServer().getPluginManager().registerEvents(this, this);
}
@EventHandler
public void onFastTest(final AsyncPlayerChatEvent event) {
String message = event.getMessage();
final String[] args = message.split(" ");
if (args[0].equals("respawn")) {
// Location location = Bukkit.getWorld(args[1]).getSpawnLocation();
getServer().getScheduler().runTask(this, new Runnable() {
@Override
public void run() {
event.getPlayer().addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, 40, 1));
}
});
Location location = new Location(Bukkit.getWorld(args[1]), event.getPlayer().getLocation().getX(), event.getPlayer().getLocation().getY(), event.getPlayer().getLocation().getZ());
moveToWorld(event.getPlayer(), location);
}
}
public void moveToWorld(final Player player, final Location location) {
getServer().getScheduler().runTask(this, new Runnable() {
@Override
public void run() {
World toWorld = location.getWorld();
World fromWorld = player.getWorld();
if (toWorld.getEnvironment() != fromWorld.getEnvironment() || fromWorld.equals(toWorld)) {
player.teleport(location);
return;
}
EntityPlayer nmsPlayer = ((CraftPlayer) player).getHandle();
WorldServer nmsFromWorld = ((CraftWorld) fromWorld).getHandle();
player.sendMessage("Before world (bukkit): " + player.getWorld().getName());
player.sendMessage("Before world (nms): " + nmsPlayer.x().getDataManager().getWorldData().getName());
// stop riding!
nmsPlayer.stopRiding();
// kill all old entities
for (Entity entity : fromWorld.getEntities()) {
if (entity.getEntityId() == player.getEntityId()) // ???
continue;
nmsPlayer.playerConnection.sendPacket(new PacketPlayOutEntityDestroy(new int[] { entity.getEntityId() }));
}
// unload old chunks
for (Chunk chunk : fromWorld.getLoadedChunks()) {
nmsPlayer.playerConnection.sendPacket(new PacketPlayOutUnloadChunk(chunk.getX(), chunk.getZ()));
}
// untrack player from entity tracker in old world
nmsFromWorld.getTracker().untrackPlayer(nmsPlayer);
// remove from player chunk map
nmsFromWorld.getPlayerChunkMap().removePlayer(nmsPlayer);
// remove entity from player world
nmsFromWorld.removeEntity(nmsPlayer);
// new world
WorldServer nmsToWorld = ((CraftWorld) toWorld).getHandle();
// copypasta from PlayerList.moveToWorld()
nmsPlayer.viewingCredits = false;
nmsPlayer.playerConnection = nmsPlayer.playerConnection;
nmsPlayer.copyTo(nmsPlayer, true);
nmsPlayer.h(nmsPlayer.getId());
nmsPlayer.v(nmsPlayer);
nmsPlayer.a(nmsPlayer.getMainHand());
Iterator<?> iterator = nmsPlayer.P().iterator();
while (iterator.hasNext()) {
String s = (String) iterator.next();
nmsPlayer.a(s);
}
nmsPlayer.forceSetPositionRotation(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
nmsToWorld.getChunkProviderServer().getChunkAt((int) nmsPlayer.locX >> 4, (int) nmsPlayer.locZ >> 4);
if (nmsToWorld.dimension != nmsFromWorld.dimension || nmsToWorld.getDifficulty() != nmsFromWorld.getDifficulty() || nmsToWorld.getWorldData().getType() != nmsFromWorld.getWorldData().getType()) {
nmsPlayer.playerConnection.sendPacket(new PacketPlayOutRespawn(nmsToWorld.dimension, nmsToWorld.getDifficulty(), nmsToWorld.getWorldData().getType(), nmsPlayer.playerInteractManager.getGameMode()));
}
nmsPlayer.spawnIn(nmsToWorld);
nmsPlayer.dead = false;
nmsPlayer.playerConnection.teleport(new Location(nmsToWorld.getWorld(), nmsPlayer.locX, nmsPlayer.locY, nmsPlayer.locZ, nmsPlayer.yaw, nmsPlayer.pitch));
// nmsPlayer.setSneaking(false);
BlockPosition blockposition1 = nmsToWorld.getSpawn();
nmsPlayer.playerConnection.sendPacket(new PacketPlayOutSpawnPosition(blockposition1));
nmsPlayer.playerConnection.sendPacket(new PacketPlayOutExperience(nmsPlayer.exp, nmsPlayer.expTotal, nmsPlayer.expLevel));
updateWorldForPlayer(nmsPlayer, nmsToWorld);
nmsPlayer.server.getPlayerList().f(nmsPlayer);
if (!(nmsPlayer.playerConnection.isDisconnected())) {
// register player in new world
nmsToWorld.getPlayerChunkMap().addPlayer(nmsPlayer);
nmsToWorld.addEntity(nmsPlayer);
}
nmsPlayer.setHealth(nmsPlayer.getHealth());
updateClient(nmsPlayer);
nmsPlayer.updateAbilities();
for (Iterator<MobEffect> respawnEvent = nmsPlayer.getEffects().iterator(); respawnEvent.hasNext();) {
Object o1 = respawnEvent.next();
MobEffect mobEffect = (MobEffect) o1;
nmsPlayer.playerConnection.sendPacket(new PacketPlayOutEntityEffect(nmsPlayer.getId(), mobEffect));
}
if (fromWorld != location.getWorld()) {
PlayerChangedWorldEvent event = new PlayerChangedWorldEvent(player, fromWorld);
getServer().getPluginManager().callEvent(event);
}
player.sendMessage("After world (bukkit): " + player.getWorld().getName());
player.sendMessage("After world (nms): " + nmsPlayer.x().getDataManager().getWorldData().getName());
}
});
}
public void updateWorldForPlayer(EntityPlayer entityplayer, WorldServer worldserver) {
WorldBorder worldborder = entityplayer.world.getWorldBorder();
entityplayer.playerConnection.sendPacket(new PacketPlayOutWorldBorder(worldborder, PacketPlayOutWorldBorder.EnumWorldBorderAction.INITIALIZE));
entityplayer.playerConnection.sendPacket(new PacketPlayOutUpdateTime(worldserver.getTime(), worldserver.getDayTime(), worldserver.getGameRules().getBoolean("doDaylightCycle")));
BlockPosition blockposition = worldserver.getSpawn();
entityplayer.playerConnection.sendPacket(new PacketPlayOutSpawnPosition(blockposition));
if (!(worldserver.W())) {
return;
}
entityplayer.setPlayerWeather(WeatherType.DOWNFALL, false);
// entityplayer.updateWeather(-worldserver.o, worldserver.o, -worldserver.q, worldserver.q);
}
public void updateClient(EntityPlayer entityplayer) {
entityplayer.updateInventory(entityplayer.defaultContainer);
entityplayer.getBukkitEntity().updateScaledHealth();
entityplayer.playerConnection.sendPacket(new PacketPlayOutHeldItemSlot(entityplayer.inventory.itemInHandIndex));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment