-
-
Notifications
You must be signed in to change notification settings - Fork 34
Expand file tree
/
Copy pathPack.java
More file actions
135 lines (113 loc) · 3.8 KB
/
Pack.java
File metadata and controls
135 lines (113 loc) · 3.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package org.allaymc.api.pack;
import com.google.gson.*;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.semver4j.Semver;
import java.nio.ByteBuffer;
import java.security.MessageDigest;
import java.util.Locale;
import java.util.UUID;
/**
* @author IWareQ | Cloudburst Server | daoge_cmd
*/
@Slf4j
@Getter
public abstract class Pack implements AutoCloseable {
private final PackLoader loader;
private final PackManifest manifest;
// Will be empty if this is not an encrypted pack
private final String contentKey;
private final byte[] hash;
private final ByteBuffer buffer;
public Pack(PackLoader loader, PackManifest manifest, String contentKey) {
this.loader = loader;
this.manifest = manifest;
this.contentKey = contentKey;
var bytes = loader.readAllBytes();
try {
this.hash = MessageDigest.getInstance("SHA-256").digest(bytes);
} catch (Exception exception) {
throw new IllegalStateException("Unable to calculate the hash of pack " + getName(), exception);
}
this.buffer = ByteBuffer.allocateDirect(bytes.length);
this.buffer.put(bytes);
this.buffer.flip();
}
public String getName() {
return this.manifest.getHeader().getName();
}
public UUID getId() {
return this.manifest.getHeader().getUuid();
}
public Semver getVersion() {
return this.manifest.getHeader().getVersion();
}
public String getStringVersion() {
return this.getVersion().getVersion();
}
public int getSize() {
return this.buffer.limit();
}
public byte[] getHash() {
return this.hash;
}
public byte[] getChunk(int offset, int length) {
byte[] chunk;
if ((this.getSize() - offset) > length) {
chunk = new byte[length];
} else {
chunk = new byte[(int) (this.getSize() - offset)];
}
try {
buffer.get(offset, chunk);
} catch (Exception exception) {
log.error("An error occurred while processing the resource pack {} at offset {} and length {}", getName(), offset, length, exception);
}
return chunk;
}
public abstract Type getType();
@Override
public void close() throws Exception {
this.loader.close();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Pack that)) return false;
return this.getId().equals(that.getId());
}
@Override
public int hashCode() {
return this.getId().hashCode();
}
/**
* Type represents the type of pack.
*
* @see <a href="https://learn.microsoft.com/en-us/minecraft/creator/reference/content/addonsreference/packmanifest?view=minecraft-bedrock-stable#modules">packmanifest</a>
*/
@Getter
@RequiredArgsConstructor
public enum Type {
RESOURCES,
DATA,
WORLD_TEMPLATE,
SCRIPT;
public static class Serializer implements JsonSerializer<Type> {
@Override
public JsonElement serialize(Type src, java.lang.reflect.Type typeOfSrc, JsonSerializationContext context) {
return new JsonPrimitive(src.name().toLowerCase(Locale.ROOT));
}
}
public static class Deserializer implements JsonDeserializer<Type> {
@Override
public Type deserialize(JsonElement json, java.lang.reflect.Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
return Type.valueOf(json.getAsString().toUpperCase(Locale.ROOT));
}
}
}
@FunctionalInterface
public interface Factory {
Pack create(PackLoader loader, PackManifest manifest);
}
}