Thread: Loading models past 65k

Results 1 to 3 of 3
  1. #1 Loading models past 65k 
    Registered Member

    Join Date
    Feb 2016
    Posts
    220
    Thanks given
    160
    Thanks received
    48
    Rep Power
    94
    Fixed thanks to Dev Az
    Reply With Quote  
     

  2. #2  
    Registered Member

    Join Date
    Feb 2016
    Posts
    220
    Thanks given
    160
    Thanks received
    48
    Rep Power
    94
    Quote Originally Posted by anon strike View Post
    Is this Volantis' Decompressor class? lol
    No? I got this from Leanbow

    Quote Originally Posted by Leanbow View Post
    Code:
    import java.io.IOException;
    import java.nio.ByteBuffer;
    import java.nio.channels.FileChannel;
    
    /**
     * Manages the reading and writing for a particular file store in the cache.
     */
    public class FileStore {
    
    	private static final int IDX_BLOCK_LEN = 6;
    	private static final int HEADER_LEN = 8;
        private static final int EXPANDED_HEADER_LEN = 10;
    	private static final int BLOCK_LEN = 512;
        private static final int EXPANDED_BLOCK_LEN = 510;
    	private static final int TOTAL_BLOCK_LEN = HEADER_LEN + BLOCK_LEN;
    	private static ByteBuffer tempBuffer = ByteBuffer.allocateDirect(TOTAL_BLOCK_LEN);
    
    	private int index;
    	private FileChannel indexChannel;
    	private FileChannel dataChannel;
    	private int maxSize;
    
    	/**
    	 * Creates a new FileStore object.
    	 * @param index The index of this file store.
    	 * @param dataChannel The channel of the data file for this file store.
    	 * @param indexChannel The channel of the index file for this file store.
    	 * @param maxSize The maximum size of a file in this file store.
    	 */
    	public FileStore(int index, FileChannel dataChannel,
    					 FileChannel indexChannel, int maxSize) {
    		this.index = index;
    		this.dataChannel = dataChannel;
    		this.indexChannel = indexChannel;
    		this.maxSize = maxSize;
    	}
    
    	/**
    	 * Gets the number of files stored in this file store.
    	 * @return This file store's file count.
    	 */
    	public int getFileCount() {
    		try {
    			return (int) (indexChannel.size() / IDX_BLOCK_LEN);
    		} catch (IOException ex) {
    			return 0;
    		}
    	}
    
    	/**
    	 * Reads a file from the file store.
    	 * @param file The file to read.
    	 * @return The file's data, or null if the file was invalid.
    	 */
    	public mgi.tools.rseditor.core.utilities.ByteBuffer get(int file) {
    		try {
    			if (file * IDX_BLOCK_LEN + IDX_BLOCK_LEN > indexChannel.size()) {
    				return null;
    			}
    
    			tempBuffer.position(0).limit(IDX_BLOCK_LEN);
    			indexChannel.read(tempBuffer, file * IDX_BLOCK_LEN);
    			tempBuffer.flip();
    			int size = getMediumInt(tempBuffer);
    			int block = getMediumInt(tempBuffer);
    
    			if (size < 0 || size > maxSize) {
    				return null;
    			}
    			if (block <= 0 || block > dataChannel.size() / TOTAL_BLOCK_LEN) {
    				return null;
    			}
    
    			mgi.tools.rseditor.core.utilities.ByteBuffer fileBuffer = new mgi.tools.rseditor.core.utilities.ByteBuffer(size);
    			int remaining = size;
    			int chunk = 0;
    			int blockLen = file <= 0xffff ? BLOCK_LEN : EXPANDED_BLOCK_LEN;
                int headerLen = file <= 0xffff ? HEADER_LEN : EXPANDED_HEADER_LEN;
                while (remaining > 0) {
    				if (block == 0) {
    					return null;
    				}
    
    				int blockSize = remaining > blockLen ? blockLen : remaining;
    				tempBuffer.position(0).limit(blockSize + headerLen);
    				dataChannel.read(tempBuffer, block * TOTAL_BLOCK_LEN);
    				tempBuffer.flip();
    
    				int currentFile, currentChunk, nextBlock, currentIndex;
                    
                    if (file <= 65535) {
                        currentFile = tempBuffer.getShort() & 0xffff;
                        currentChunk = tempBuffer.getShort() & 0xffff;
                        nextBlock = getMediumInt(tempBuffer);
                        currentIndex = tempBuffer.get() & 0xff;
                    } else {
                        currentFile = tempBuffer.getInt();
                        currentChunk = tempBuffer.getShort() & 0xffff;
                        nextBlock = getMediumInt(tempBuffer);
                        currentIndex = tempBuffer.get() & 0xff;
                    }
    
    				if (file != currentFile || chunk != currentChunk || index != currentIndex) {
    					return null;
    				}
    				if (nextBlock < 0 || nextBlock > dataChannel.size() / TOTAL_BLOCK_LEN) {
    					return null;
    				}
    
    				int rem = tempBuffer.remaining();
    				for (int i = 0; i < rem; i++)
    					fileBuffer.writeByte(tempBuffer.get());
    
    				remaining -= blockSize;
    				block = nextBlock;
    				chunk++;
    			}
    
    			fileBuffer.setPosition(0);
    			return fileBuffer;
    		} catch (IOException ex) {
    			return null;
    		}
    	}
    
    	/**
    	 * Writes an item to the file store.
    	 * @param file The file to write.
    	 * @param data The file's data.
    	 * @param size The size of the file.
    	 * @return true if the file was written, false otherwise.
    	 */
    	public boolean put(int file, mgi.tools.rseditor.core.utilities.ByteBuffer data, int size) {
    		if (size < 0 || size > maxSize) {
    			throw new IllegalArgumentException("File too big: " + file + " size: " + size);
    		}
    
    		boolean success = put(file, ByteBuffer.wrap(data.getBuffer()), size, true);
    		if (!success) {
    			success = put(file, ByteBuffer.wrap(data.getBuffer()), size, false);
    		}
    
    		return success;
    	}
    
    	private boolean put(int file, ByteBuffer data, int size, boolean exists) {
    		try {
                int block;
    			if (exists) {
    				if (file * IDX_BLOCK_LEN + IDX_BLOCK_LEN > indexChannel.size()) {
    					return false;
    				}
    
    				tempBuffer.position(0).limit(IDX_BLOCK_LEN);
    				indexChannel.read(tempBuffer, file * IDX_BLOCK_LEN);
    				tempBuffer.flip().position(3);
    				block = getMediumInt(tempBuffer);
    
    				if (block <= 0 || block > dataChannel.size() / TOTAL_BLOCK_LEN) {
    					return false;
    				}
    			} else {
    				block = (int) (dataChannel.size() + TOTAL_BLOCK_LEN - 1) / TOTAL_BLOCK_LEN;
    				if (block == 0) {
    					block = 1;
    				}
    			}
    
    			tempBuffer.position(0);
    			putMediumInt(tempBuffer, size);
    			putMediumInt(tempBuffer, block);
    			tempBuffer.flip();
    			indexChannel.write(tempBuffer, file * IDX_BLOCK_LEN);
    
    			int remaining = size;
    			int chunk = 0;
                int blockLen = file <= 0xffff ? BLOCK_LEN : EXPANDED_BLOCK_LEN;
                int headerLen = file <= 0xffff ? HEADER_LEN : EXPANDED_HEADER_LEN;
    			while (remaining > 0) {
    				int nextBlock = 0;
    				if (exists) {
    					tempBuffer.position(0).limit(headerLen);
    					dataChannel.read(tempBuffer, block * TOTAL_BLOCK_LEN);
    					tempBuffer.flip();
    
    					int currentFile, currentChunk, currentIndex;
                        if (file <= 0xffff) {
                            currentFile = tempBuffer.getShort() & 0xffff;
                            currentChunk = tempBuffer.getShort() & 0xffff;
                            nextBlock = getMediumInt(tempBuffer);
                            currentIndex = tempBuffer.get() & 0xff;
                        } else {
                            currentFile = tempBuffer.getInt();
                            currentChunk = tempBuffer.getShort() & 0xffff;
                            nextBlock = getMediumInt(tempBuffer);
                            currentIndex = tempBuffer.get() & 0xff;
                        }
    
    					if (file != currentFile || chunk != currentChunk || index != currentIndex) {
    						return false;
    					}
    					if (nextBlock < 0 || nextBlock > dataChannel.size() / TOTAL_BLOCK_LEN) {
    						return false;
    					}
    				}
    
    				if (nextBlock == 0) {
    					exists = false;
    					nextBlock = (int) ((dataChannel.size() + TOTAL_BLOCK_LEN - 1) / TOTAL_BLOCK_LEN);
    					if (nextBlock == 0) {
    						nextBlock = 1;
    					}
    					if (nextBlock == block) {
    						nextBlock++;
    					}
    				}
    
    				if (remaining <= blockLen) {
    					nextBlock = 0;
    				}
                    tempBuffer.position(0).limit(TOTAL_BLOCK_LEN);
                    if (file <= 0xffff) {
                        tempBuffer.putShort((short) file);
                        tempBuffer.putShort((short) chunk);
                        putMediumInt(tempBuffer, nextBlock);
                        tempBuffer.put((byte) index);
                    } else {
                        tempBuffer.putInt(file);
                        tempBuffer.putShort((short) chunk);
                        putMediumInt(tempBuffer, nextBlock);
                        tempBuffer.put((byte) index);
                    }
    
    				int blockSize = remaining > blockLen ? blockLen : remaining;
    				data.limit(data.position() + blockSize);
    				tempBuffer.put(data);
    				tempBuffer.flip();
    
    				dataChannel.write(tempBuffer, block * TOTAL_BLOCK_LEN);
    				remaining -= blockSize;
    				block = nextBlock;
    				chunk++;
    			}
    
    			return true;
    		} catch (IOException ex) {
    			return false;
    		}
    	}
    
    	private static int getMediumInt(ByteBuffer buffer) {
    		return ((buffer.get() & 0xff) << 16) | ((buffer.get() & 0xff) << 8) |
    				(buffer.get() & 0xff);
    	}
    
    	private static void putMediumInt(ByteBuffer buffer, int val) {
    		buffer.put((byte) (val >> 16));
    		buffer.put((byte) (val >> 8));
    		buffer.put((byte) val);
    	}
    	
    	public void setMaxSize(int size) {
    		this.maxSize = size;
    	}
    	
    	/**
    	 * Close's this store.
    	 */
    	public void close() {
    		try { this.dataChannel.close(); } catch (IOException e) {}
    		try { this.indexChannel.close(); } catch (IOException e) {}
    	}
    
    }
    Reply With Quote  
     

  3. #3  
    Interfacing with your sister

    Streax's Avatar
    Join Date
    Jun 2009
    Posts
    2,311
    Thanks given
    782
    Thanks received
    175
    Rep Power
    229
    I may be mistaken, but you'll need to make sure you disable crc checks in OnDemandFetcher, and also in Model class method459 (naming may be different) increase amounts of models which can be loaded by changing this property:

    Code:
    aClass21Array1661 = new ModelHeader[i + 1]; // i + 90000
    That should be it, but I might be missing a few steps.
    Reply With Quote  
     

  4. Thankful user:



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. Loading models over 65k
    By Kenneh in forum Help
    Replies: 2
    Last Post: 06-07-2012, 12:40 AM
  2. Modified RSMV (SHOWS MODELS PAST 30000)
    By Clienthax in forum Models
    Replies: 77
    Last Post: 02-16-2011, 08:33 PM
  3. Help with loading models correctly
    By waffl3z0wnu in forum Help
    Replies: 0
    Last Post: 01-26-2009, 04:01 PM
  4. Auto Load models from model folder
    By Bulby Strife in forum Tutorials
    Replies: 6
    Last Post: 04-14-2008, 03:42 AM
  5. New method to load models!!!
    By Dezzy in forum Tutorials
    Replies: 7
    Last Post: 12-27-2007, 07:40 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
  •