RuneHive-Tarnish
Neural OSRS Enhancement Framework
Loading...
Searching...
No Matches
FileSystem.java
1package com.osroyale.fs.cache;
2
3import com.google.common.base.Preconditions;
4import com.osroyale.fs.cache.archive.Archive;
5
6import java.io.IOException;
7import java.nio.ByteBuffer;
8import java.nio.channels.SeekableByteChannel;
9import java.nio.file.Files;
10import java.nio.file.Path;
11import java.nio.file.Paths;
12import java.util.Objects;
13import java.util.zip.CRC32;
14
15import static java.nio.file.StandardOpenOption.READ;
16import static java.nio.file.StandardOpenOption.WRITE;
17
48
49public final class FileSystem {
50
52 public static final int CONFIG_INDEX = 0;
53
55 public static final int MODEL_INDEX = 1;
56
58 public static final int ANIMATION_INDEX = 2;
59
61 public static final int MIDI_INDEX = 3;
62
64 public static final int MAP_INDEX = 4;
65
67 public static final int TITLE_ARCHIVE = 1;
68
70 public static final int CONFIG_ARCHIVE = 2;
71
73 public static final int INTERFACE_ARCHIVE = 3;
74
76 public static final int MEDIA_ARCHIVE = 4;
77
79 public static final int MANIFEST_ARCHIVE = 5;
80
82 public static final int TEXTURES_ARCHIVE = 6;
83
88 public static final int WORD_ARCHIVE = 7;
89
91 public static final int SOUND_ARCHIVE = 8;
92
94 private static final int MAXIMUM_ARCHIVES = 9;
95
97 private static final int MAXIMUM_INDICES = 256;
98
100 private static final String DATA_PREFIX = "main_file_cache.dat";
101
103 private static final String INDEX_PREFIX = "main_file_cache.idx";
104
106 private final Cache[] caches;
107
109 private final Archive[] archives;
110
112 private ByteBuffer archiveHashes;
113
123 private FileSystem(Cache[] caches, Archive[] archives) {
124 this.caches = caches;
125 this.archives = archives;
126 }
127
136 public static FileSystem create(String directory) throws IOException {
137 Path root = Paths.get(directory);
138 Preconditions.checkArgument(Files.isDirectory(root), "Supplied path must be a directory! " + root);
139
140 Path data = root.resolve(DATA_PREFIX);
141 Preconditions.checkArgument(Files.exists(data), "No data file found in the specified path!");
142
143 SeekableByteChannel dataChannel = Files.newByteChannel(data, READ, WRITE);
144
145 Cache[] caches = new Cache[MAXIMUM_INDICES];
146 Archive[] archives = new Archive[MAXIMUM_ARCHIVES];
147
148 for (int index = 0; index < caches.length; index++) {
149 Path path = root.resolve(INDEX_PREFIX + index);
150 if (Files.exists(path)) {
151 SeekableByteChannel indexChannel = Files.newByteChannel(path, READ, WRITE);
152 caches[index] = new Cache(dataChannel, indexChannel, index);
153 }
154 }
155
156 // We don't use index 0
157 for (int id = 1; id < archives.length; id++) {
158 Cache cache = Objects.requireNonNull(caches[CONFIG_INDEX], "Configuration cache is null - unable to decode archives");
159 archives[id] = Archive.decode(cache.get(id));
160 }
161
162 return new FileSystem(caches, archives);
163 }
164
173 public Archive getArchive(int id) {
174 Preconditions.checkElementIndex(id, archives.length);
175 return Objects.requireNonNull(archives[id]);
176 }
177
186 public Cache getCache(int id) {
187 Preconditions.checkElementIndex(id, caches.length);
188 return Objects.requireNonNull(caches[id]);
189 }
190
200 public ByteBuffer getFile(int cacheId, int indexId) throws IOException {
201 Cache cache = getCache(cacheId);
202 synchronized (cache) {
203 return cache.get(indexId);
204 }
205 }
206
214 public ByteBuffer getArchiveHashes() throws IOException {
215 synchronized (this) {
216 if (archiveHashes != null) {
217 return archiveHashes.duplicate();
218 }
219 }
220
221 int[] crcs = new int[MAXIMUM_ARCHIVES];
222
223 CRC32 crc32 = new CRC32();
224 for (int file = 1; file < crcs.length; file++) {
225 crc32.reset();
226
227 ByteBuffer buffer = getFile(CONFIG_INDEX, file);
228 crc32.update(buffer);
229
230 crcs[file] = (int) crc32.getValue();
231 }
232
233 ByteBuffer buffer = ByteBuffer.allocate((crcs.length + 1) * Integer.BYTES);
234
235 int hash = 1234;
236 for (int crc : crcs) {
237 hash = (hash << 1) + crc;
238 buffer.putInt(crc);
239 }
240
241 buffer.putInt(hash);
242 buffer.flip();
243
244 synchronized (this) {
245 archiveHashes = buffer.asReadOnlyBuffer();
246 return archiveHashes.duplicate();
247 }
248 }
249
250}
ByteBuffer getFile(int cacheId, int indexId)
static FileSystem create(String directory)
static Archive decode(ByteBuffer data)
Definition Archive.java:82