From cc1b0a005cdb14007c4647599a984967ff637659 Mon Sep 17 00:00:00 2001
From: EvilSeph <evilseph@unaligned.org>
Date: Fri, 17 Jun 2011 02:29:16 -0400
Subject: [PATCH] Added per player time support. Thanks eisental, Shamebot and
 needspeed10!

---
 .../net/minecraft/server/EntityPlayer.java    | 13 ++++++++++++
 .../net/minecraft/server/MinecraftServer.java |  4 ++--
 .../net/minecraft/server/NetLoginHandler.java |  2 +-
 .../org/bukkit/craftbukkit/CraftWorld.java    |  2 +-
 .../craftbukkit/entity/CraftPlayer.java       | 21 +++++++++++++++++++
 5 files changed, 38 insertions(+), 4 deletions(-)

diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java
index f839b20d40..5cd8ab1def 100644
--- a/src/main/java/net/minecraft/server/EntityPlayer.java
+++ b/src/main/java/net/minecraft/server/EntityPlayer.java
@@ -483,6 +483,19 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
     }
 
     // CraftBukkit start
+    public long timeOffset = 0;
+    public boolean relativeTime = true;
+
+    public long getPlayerTime() {
+        if (relativeTime) {
+            // Adds timeOffset to the current server time.
+            return world.getTime() + timeOffset;
+        } else {
+            // Adds timeOffset to the beginning of this day.
+            return world.getTime() - (world.getTime() % 24000) + timeOffset;
+        }
+    }
+
     @Override
     public String toString() {
         return super.toString() + "(" + name + " at " + locX + "," + locY + "," + locZ + ")";
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 8df7fb4595..bdd733c82d 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -177,7 +177,7 @@ public class MinecraftServer implements Runnable, ICommandListener {
 
                 File newWorld = new File(new File(name), dim);
                 File oldWorld = new File(new File(s), dim);
-                
+
                 if ((!newWorld.isDirectory()) && (oldWorld.isDirectory())) {
                     log.info("---- Migration of old " + worldType + " folder required ----");
                     log.info("Unfortunately due to the way that Minecraft implemented multiworld support in 1.6, Bukkit requires that you move your " + worldType + " folder to a new location in order to operate correctly.");
@@ -411,7 +411,7 @@ public class MinecraftServer implements Runnable, ICommandListener {
                     // CraftBukkit start - only send timeupdates to the people in that world
                     for (int i = 0; i < this.serverConfigurationManager.players.size(); ++i) {
                         EntityPlayer entityplayer = (EntityPlayer) this.serverConfigurationManager.players.get(i);
-                        entityplayer.netServerHandler.sendPacket(new Packet4UpdateTime(entityplayer.world.getTime()));
+                        entityplayer.netServerHandler.sendPacket(new Packet4UpdateTime(entityplayer.getPlayerTime())); // Add support for per player time
                     }
                 }
 
diff --git a/src/main/java/net/minecraft/server/NetLoginHandler.java b/src/main/java/net/minecraft/server/NetLoginHandler.java
index 88d9565cab..473b498999 100644
--- a/src/main/java/net/minecraft/server/NetLoginHandler.java
+++ b/src/main/java/net/minecraft/server/NetLoginHandler.java
@@ -97,7 +97,7 @@ public class NetLoginHandler extends NetHandler {
             this.server.serverConfigurationManager.c(entityplayer);
             netserverhandler.a(entityplayer.locX, entityplayer.locY, entityplayer.locZ, entityplayer.yaw, entityplayer.pitch);
             this.server.networkListenThread.a(netserverhandler);
-            netserverhandler.sendPacket(new Packet4UpdateTime(worldserver.getTime()));
+            netserverhandler.sendPacket(new Packet4UpdateTime(entityplayer.getPlayerTime())); // CraftBukkit - add support for player specific time
             entityplayer.syncInventory();
         }
 
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index 486d939e8a..3053937d31 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -424,7 +424,7 @@ public class CraftWorld implements World {
         // Forces the client to update to the new time immediately
         for (Player p: getPlayers()) {
             CraftPlayer cp = (CraftPlayer) p;
-            cp.getHandle().netServerHandler.sendPacket(new Packet4UpdateTime(time));
+            cp.getHandle().netServerHandler.sendPacket(new Packet4UpdateTime(cp.getHandle().getPlayerTime()));
         }
     }
 
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index 20b539bd39..56f9f6ce27 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -297,4 +297,25 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
 
         getHandle().netServerHandler.sendPacket(new Packet200Statistic(id, amount));
     }
+
+    public void setPlayerTime(long time, boolean relative) {
+        getHandle().timeOffset = time;
+        getHandle().relativeTime = relative;
+    }
+
+    public long getPlayerTimeOffset() {
+        return getHandle().timeOffset;
+    }
+
+    public long getPlayerTime() {
+        return getHandle().getPlayerTime();
+    }
+
+    public boolean isPlayerTimeRelative() {
+        return getHandle().relativeTime;
+    }
+
+    public void resetPlayerTime() {
+        setPlayerTime(0, true);
+    }
 }