Thread: [PI] Server-Sided Cache Loading

Page 1 of 4 123 ... LastLast
Results 1 to 10 of 38
  1. #1 [PI] Server-Sided Cache Loading 
    Registered Member
    Join Date
    Dec 2009
    Posts
    84
    Thanks given
    48
    Thanks received
    25
    Rep Power
    14
    Too many people are still using that worldmap.bin thing that Martin released like 2 years ago or something.
    People who are using it mention it and there is always that person who tells them "Just load the cache from the server," but things just haven't changed.

    Spoiler for Random bullshit:
    Anyway, today I was lurking the snippets board like I normally do, just to look for something that I could put to use that I haven't thought of, or something that I'm too lazy to do myself, and found this.

    [Only registered and activated users can see links. ]

    This caught my attention, cause I was playing with doors.cfg, and after a while, I got extremely frustrated and gave up. I now hate all doors, in both rsps and irl.

    At the end of the OP, I saw the SVN links to Graham's region and cache packages from his Hyperion base. I instantly thought of server sided cache loading, and decided to get to work.

    Eventually I was able to get the cache loading fully functional for my PI server, but I wasn't able to get as much use out of it as I hoped I would (It won't load my cache correctly...), so I figured I would just release it.




    Difficulty: 4? / 10
    You gotta be able to add directories to your compiler and add libraries to your server runner and compiler. I've never had to do this before, so the difficulty is based off of my assumption that at least 1/4th the people who work with PI haven't either.

    Classes Modified:
    server.world.WorldMap.java

    You are also going to be adding a lot of classes that are small modifications of classes from Hyperion.

    While you are extracing any zip files, make sure you are extracting them correctly.
    To be safe, simply drag the folder inside the archive into the directed location.








    Step 1: Downloading and adding the cache

    Download this file.
    [Only registered and activated users can see links. ]

    Spoiler for More shit:
    This is the cache that was being loaded from the Hyperion server in the SVN.
    This is the only cache, among the ones that I tried, that worked.
    It did not load my cache, or PJA's 453 cache without failing.
    You might want to try your's anyway. If it works, then use it instead.

    Extract the folder into your Data folder. You can find it in the same location as the batch file that runs your server.







    Step 2: Adding the necessary library

    Download this library.
    [Only registered and activated users can see links. ]

    Drag that into your deps folder. You can find it in the same location as the Data folder.







    Step 3: Adding the cache package

    Download this package.
    [Only registered and activated users can see links. ]

    Drag the folder inside this archive into src.server. This is the same folder that has your Server.java and Config.java in it.







    Step 4: Adding the region package

    Download this package.
    [Only registered and activated users can see links. ]

    Drag the folder inside this archive into src.server.world. This is the same folder that has your WorldMap.java in it.







    Step 5: Adding the background runner class

    Create a new java file titled BlockingExecutorService.java, paste the following code into it, and save it in the src.server.util folder.

    Code:
    package server.util;
    
    import java.util.Collection;
    import java.util.List;
    import java.util.concurrent.BlockingQueue;
    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Future;
    import java.util.concurrent.LinkedBlockingQueue;
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.TimeoutException;
    
    /**
     * An <code>ExecutorService</code> that waits for all its events to finish
     * executing.
     * @author Graham Edgecombe
     *
     */
    public class BlockingExecutorService implements ExecutorService {
    	
    	/**
    	 * The service backing this service.
    	 */
    	private ExecutorService service;
    	
    	/**
    	 * A list of pending tasks.
    	 */
    	private BlockingQueue<Future<?>> pendingTasks = new LinkedBlockingQueue<Future<?>>();
    	
    	/**
    	 * Creates the executor service.
    	 * @param service The service backing this service.
    	 */
    	public BlockingExecutorService(ExecutorService service) {
    		this.service = service;
    	}
    	
    	/**
    	 * Waits for pending tasks to complete.
    	 * @throws ExecutionException if an error in a task occurred.
    	 */
    	public void waitForPendingTasks() throws ExecutionException {
    		while(pendingTasks.size() > 0) {
    			if(isShutdown()) {
    				return;
    			}
    			try {
    				pendingTasks.take().get();
    			} catch(InterruptedException e) {
    				continue;
    			}
    		}
    	}
    	
    	/**
    	 * Gets the number of pending tasks.
    	 * @return The number of pending tasks.
    	 */
    	public int getPendingTaskAmount() {
    		return pendingTasks.size();
    	}
    
    	@Override
    	public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException {
    		return service.awaitTermination(timeout, unit);
    	}
    
    	@Override
    	public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException {
    		List<Future<T>> futures = service.invokeAll(tasks);
    		for(Future<?> future : futures) {
    			pendingTasks.add(future);
    		}
    		return futures;
    	}
    
    	@Override
    	public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException {
    		List<Future<T>> futures = service.invokeAll(tasks, timeout, unit);
    		for(Future<?> future : futures) {
    			pendingTasks.add(future);
    		}
    		return futures;
    	}
    
    	@Override
    	public <T> T invokeAny(Collection<? extends Callable<T>> tasks) throws InterruptedException, ExecutionException {
    		return service.invokeAny(tasks);
    	}
    
    	@Override
    	public <T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
    		return service.invokeAny(tasks, timeout, unit);
    	}
    
    	@Override
    	public boolean isShutdown() {
    		return service.isShutdown();
    	}
    
    	@Override
    	public boolean isTerminated() {
    		return service.isTerminated();
    	}
    
    	@Override
    	public void shutdown() {
    		service.shutdown();
    	}
    
    	@Override
    	public List<Runnable> shutdownNow() {
    		return service.shutdownNow();
    	}
    
    	@Override
    	public <T> Future<T> submit(Callable<T> task) {
    		Future<T> future = service.submit(task);
    		pendingTasks.add(future);
    		return future;
    	}
    
    	@Override
    	public Future<?> submit(Runnable task) {
    		Future<?> future = service.submit(task);
    		pendingTasks.add(future);
    		return future;
    	}
    
    	@Override
    	public <T> Future<T> submit(Runnable task, T result) {
    		Future<T> future = service.submit(task, result);
    		pendingTasks.add(future);
    		return future;
    	}
    
    	@Override
    	public void execute(Runnable command) {
    		service.execute(command);
    	}
    
    }






    Step 6: Modifying your WorldMap class

    Open up src.server.world.WorldMap.java

    Add these four imports to the class.
    Code:
    import java.util.concurrent.Callable;
    import java.util.concurrent.Executors;
    import server.cache.model.ObjectManager;
    import server.util.BlockingExecutorService;
    import server.world.GameObject;
    Replace this line...
    Code:
    GameObject go = new GameObject(objectId, objectType, objectX, objectY, objectFace);
    ...With this one...
    Code:
    GameObject go = new GameObject(objectId, objectType, objectX, objectY, objectHeight, objectFace);
    Right below this line...
    Code:
    public final class WorldMap {
    ...Paste this...
    Code:
    public static int getObjectType(int x, int y) {
    		GameObject go = gameObjects.get(y + (x << 16));
    		if (go != null && go.x() == x && go.y() == y) {
    			return go.type();
    		}
    		return -1;
    	}
    	
    	private BlockingExecutorService backgroundLoader = new BlockingExecutorService(Executors.newSingleThreadExecutor());
    	
    	public BlockingExecutorService getBackgroundLoader() {
    		return backgroundLoader;
    	}
    	
    	private static final WorldMap worldMap = new WorldMap();
    	private ObjectManager objectManager;
    	
    	public static WorldMap getWorld() {
    		return worldMap;
    	}
    	
    	public WorldMap() {
    		backgroundLoader.submit(new Callable<Object>() {
    			@Override
    			public Object call() throws Exception {
    				objectManager = new ObjectManager();
    				objectManager.load();
    				return null;
    			}
    		});
    	}	
    	
    	public static void addObject(int id, int x, int y, int height, int type, int face) {
    		//System.out.println("Adding clipped object.");
    		GameObject go = new GameObject(id, type, x, y, height, face);
    		if (go.type() != 0) {
    			gameObjects.put(go.y() + (go.x() << 16), go);
    		}
    	}
    The only thing I wrote in the above code was the getObjectType variable. This variable returns the type of object that exists in the coords given. If there isn't an object at the given coords, it returns -1.







    Step 7: Modifying the GameObject class

    Open up src.server.world.GameObject.java, and replace the entire class with this...

    Code:
    package server.world;
    
    public final class GameObject {
        private int id;
        private int type;
        private int x;
        private int y;
    	private int height;
        private int face;
    
        public GameObject(int id, int type, int x, int y, int height, int face) {
            this.id = id;
            this.type = type;
            this.x = x;
            this.y = y;
    		this.height = height;
            this.face = face;
        }
    
        public int id() {
            return id;
        }
    
        public int type() {
            return type;
        }
    
        public int x() {
            return x;
        }
    
        public int y() {
            return y;
        }
    	
    	public int height() {
            return height;
        }
    
    	public int getFace() {
    		return face;
    	}
    }






    Step 8: Calling the cache loader on server startup

    Open up Server.java, and below this line...
    Code:
    public static void main(java.lang.String args[]) throws NullPointerException, IOException {
    ...Paste this...
    Code:
    WorldMap.getWorld();
    If you get an error that says "Cannot find symbol WorldMap" or something, add the following import to your Server.java...
    Code:
    import server.world.WorldMap;






    Step 9: Modifying your compiler and server runner
    Final step yay

    Add the following paths into your Build.bat/Compiler.bat...
    Code:
    src\server\cache\*.java src\server\world\region\*.java src\server\cache\index\*.java src\server\cache\index\impl\*.java src\server\cache\model\*.java src\server\cache\map\*.java src\server\cache\obj\*.java src\server\cache\util\*.java
    Add the following library to your Run.bat/Start Server.bat and your Build.bat/Compiler.bat...
    Code:
    deps/commons-compress-1.0.jar;
    I am not going to make this any clearer.
    If you look at it for like 5 minutes you should be able to figure it out.
    I don't even like batch files because paths and libraries all need to be jam packed into one line, and when you have word wrap on, it's barely readable.
    If you don't already know how to add libraries and paths to batch files, then good luck.







    And that should be it.
    It is 7.30 AM right now and I've been up all night, so I am tired and possibly forgot something.
    Post any compiling errors or issues you come across.
    I am like 95% sure I didn't forget anything though.
    Please note that even though this can definitely be used for clipping, it does not actually clip for you. That part you should be able to do yourself, with a little experimentation.
    If there are any classes that are included in the downloads that can be removed without any compiling errors/cache loading errors, let me know.


    Credits:
    95% to Graham and any other programmers who helped with Hyperion
    5% to me for making it work with Project Insanity servers >.>
    Reply With Quote  
     

  2. Thankful users:


  3. #2  
    Banned
    Join Date
    Sep 2010
    Posts
    883
    Thanks given
    20
    Thanks received
    6
    Rep Power
    0
    fixed
    Reply With Quote  
     

  4. #3  
    Registered Member
    Join Date
    Dec 2009
    Posts
    84
    Thanks given
    48
    Thanks received
    25
    Rep Power
    14
    Add these two imports to WorldMap.java...
    Code:
    import java.util.concurrent.Callable;
    import java.util.concurrent.Executors;
    ...And replace this line (Still in WorldMap.java)...
    Code:
    GameObject go = new GameObject(objectId, objectType, objectX, objectY, objectFace);
    ...With this one...
    Code:
    GameObject go = new GameObject(objectId, objectType, objectX, objectY, objectHeight, objectFace);
    Also, replace your src.server.world.GameObject.java with this one...
    Code:
    package server.world;
    
    public final class GameObject {
        private int id;
        private int type;
        private int x;
        private int y;
    	private int height;
        private int face;
    
        public GameObject(int id, int type, int x, int y, int height, int face) {
            this.id = id;
            this.type = type;
            this.x = x;
            this.y = y;
    		this.height = height;
            this.face = face;
        }
    
        public int id() {
            return id;
        }
    
        public int type() {
            return type;
        }
    
        public int x() {
            return x;
        }
    
        public int y() {
            return y;
        }
    	
    	public int height() {
            return height;
        }
    
    	public int getFace() {
    		return face;
    	}
    }



    Updated the thread.
    Reply With Quote  
     

  5. #4  
    Banned
    Join Date
    Sep 2010
    Posts
    883
    Thanks given
    20
    Thanks received
    6
    Rep Power
    0
    fixed
    Reply With Quote  
     

  6. #5  
    Registered Member
    Join Date
    Dec 2009
    Posts
    84
    Thanks given
    48
    Thanks received
    25
    Rep Power
    14
    Quote Originally Posted by Jamesfrost View Post
    fixed
    What happened that threw the 31 errors?
    Reply With Quote  
     

  7. #6  
    Banned
    Join Date
    Sep 2010
    Posts
    883
    Thanks given
    20
    Thanks received
    6
    Rep Power
    0
    import
    Code:
    import server.world.GameObject;
    in worldmap.java
    Reply With Quote  
     

  8. #7  
    Registered Member
    Join Date
    Dec 2009
    Posts
    84
    Thanks given
    48
    Thanks received
    25
    Rep Power
    14
    Quote Originally Posted by Jamesfrost View Post
    import
    Code:
    import server.world.GameObject;
    in worldmap.java
    Weird, that's not even imported in my WorldMap class and it works fine.
    Oh well, I'll add it to the OP anyway.
    Thanks for the error reports.
    Reply With Quote  
     

  9. #8  
    q.q


    Join Date
    Dec 2010
    Posts
    6,535
    Thanks given
    1,072
    Thanks received
    3,534
    Rep Power
    4752
    Hm... so basically this will load the map data directly from your cache?

    Didn't exactly understand all of it.
    Reply With Quote  
     

  10. #9  
    Banned

    Join Date
    Sep 2010
    Age
    26
    Posts
    568
    Thanks given
    147
    Thanks received
    201
    Rep Power
    0
    u forgot the Location class

    Code:
    /**
     * Represents a single location in the game world.
     * @author Graham
     */
    
    public class Location {
    	
    	/**
    	 * The x coordinate.
    	 */
    	private final int x;
    	
    	/**
    	 * The y coordinate.
    	 */
    	private final int y;
    	
    	/**
    	 * The z coordinate.
    	 */
    	private final int z;
    	
    	/**
    	 * Creates a location.
    	 * @param x The x coordinate.
    	 * @param y The y coordinate.
    	 * @param z The z coordinate.
    	 * @return The location.
    	 */
    	public static Location create(int x, int y, int z) {
    		return new Location(x, y, z);
    	}
    	
    	/**
    	 * Creates a location.
    	 * @param x The x coordinate.
    	 * @param y The y coordinate.
    	 * @param z The z coordinate.
    	 */
    	private Location(int x, int y, int z) {
    		this.x = x;
    		this.y = y;
    		this.z = z;
    	}
    	
    	/**
    	 * Gets the absolute x coordinate.
    	 * @return The absolute x coordinate.
    	 */
    	public int getX() {
    		return x;
    	}
    	
    	/**
    	 * Gets the absolute y coordinate.
    	 * @return The absolute y coordinate.
    	 */
    	public int getY() {
    		return y;
    	}
    	
    	/**
    	 * Gets the z coordinate, or height.
    	 * @return The z coordinate.
    	 */
    	public int getZ() {
    		return z;
    	}
    	
    	/**
    	 * Gets the local x coordinate relative to this region.
    	 * @return The local x coordinate relative to this region.
    	 */
    	public int getLocalX() {
    		return getLocalX(this);
    	}
    	
    	/**
    	 * Gets the local y coordinate relative to this region.
    	 * @return The local y coordinate relative to this region.
    	 */
    	public int getLocalY() {
    		return getLocalY(this);
    	}
    	
    	/**
    	 * Gets the local x coordinate relative to a specific region.
    	 * @param l The region the coordinate will be relative to.
    	 * @return The local x coordinate.
    	 */
    	public int getLocalX(Location l) {
    		return x - 8 * l.getRegionX();
    	}
    	
    	/**
    	 * Gets the local y coordinate relative to a specific region.
    	 * @param l The region the coordinate will be relative to.
    	 * @return The local y coordinate.
    	 */
    	public int getLocalY(Location l) {
    		return y - 8 * l.getRegionY();
    	}
    	
    	/**
    	 * Gets the region x coordinate.
    	 * @return The region x coordinate.
    	 */
    	public int getRegionX() {
    		return (x >> 3) - 6;
    	}
    	
    	/**
    	 * Gets the region y coordinate.
    	 * @return The region y coordinate.
    	 */
    	public int getRegionY() {
    		return (y >> 3) - 6;
    	}
    	
    	/**
    	 * Checks if this location is within range of another.
    	 * @param other The other location.
    	 * @return <code>true</code> if the location is in range,
    	 * <code>false</code> if not.
    	 */
    	public boolean isWithinDistance(Location other) {
    		if(z != other.z) {
    			return false;
    		}
    		int deltaX = other.x - x, deltaY = other.y - y;
    		return deltaX <= 14 && deltaX >= -15 && deltaY <= 14 && deltaY >= -15;
    	}
    	
    	/**
    	 * Checks if this location is within interaction range of another.
    	 * @param other The other location.
    	 * @return <code>true</code> if the location is in range,
    	 * <code>false</code> if not.
    	 */
    	public boolean isWithinInteractionDistance(Location other) {
    		if(z != other.z) {
    			return false;
    		}
    		int deltaX = other.x - x, deltaY = other.y - y;
    		return deltaX <= 2 && deltaX >= -3 && deltaY <= 2 && deltaY >= -3;
    	}
    	
    	@Override
    	public int hashCode() {
    		return z << 30 | x << 15 | y;
    	}
    	
    	@Override
    	public boolean equals(Object other) {
    		if(!(other instanceof Location)) {
    			return false;
    		}
    		Location loc = (Location) other;
    		return loc.x == x && loc.y == y && loc.z == z;
    	}
    	
    	@Override
    	public String toString() {
    		return "["+x+","+y+","+z+"]";
    	}
    
    	/**
    	 * Creates a new location based on this location.
    	 * @param diffX X difference.
    	 * @param diffY Y difference.
    	 * @param diffZ Z difference.
    	 * @return The new location.
    	 */
    	public Location transform(int diffX, int diffY, int diffZ) {
    		return Location.create(x + diffX, y + diffY, z + diffZ);
    	}
    
    }
    Reply With Quote  
     

  11. #10  
    Registered Member
    Teemuzz's Avatar
    Join Date
    Oct 2009
    Posts
    2,710
    Thanks given
    1,132
    Thanks received
    400
    Rep Power
    701
    Quote Originally Posted by Barry Cade View Post
    what did u change other than the imports and package declarations?
    The point of open-source:

    Editable and reusable software & parts.

    So it doesnt matter if he just edited.
    I'm back.
    ScapeEmulator #592 Convert [Only registered and activated users can see links. ]/[Only registered and activated users can see links. ]
    [Only registered and activated users can see links. ]
    [Only registered and activated users can see links. ]
    [Only registered and activated users can see links. ]
    Reply With Quote  
     

  12. Thankful user:


Page 1 of 4 123 ... LastLast

Thread Information
Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)


User Tag List

Similar Threads

  1. Replies: 12
    Last Post: 07-27-2011, 08:24 PM
  2. Replies: 3
    Last Post: 05-16-2011, 07:43 PM
  3. Replies: 0
    Last Post: 03-03-2011, 06:35 PM
  4. Loading curse prayers client & server sided 99% :)
    By FuckThePolice in forum Projects
    Replies: 2
    Last Post: 08-08-2010, 10:17 PM
Posting Permissions
  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •