-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathMapLoader.java
132 lines (120 loc) · 4.36 KB
/
MapLoader.java
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
/*
* This file is part of Swf Map Loader.
*
* Swf Map Loader is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Swf Map Loader is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Swf Map Loader. If not, see <https://www.gnu.org/licenses/>.
*
* Copyright (c) 2020-2020 Vincent Quatrevieux
*/
package fr.arakne.swfmaploader;
import fr.arakne.swfmaploader.cache.MapStructureCache;
import fr.arakne.swfmaploader.map.MapFactory;
import fr.arakne.swfmaploader.swf.SwfFileLoader;
import fr.arakne.swfmaploader.swf.SwfMapStructure;
import fr.arakne.utils.maps.DofusMap;
import fr.arakne.utils.maps.MapCell;
import fr.arakne.utils.maps.serializer.DefaultMapDataSerializer;
import fr.arakne.utils.maps.serializer.MapDataSerializer;
import java.io.IOException;
import java.net.URL;
/**
* Loader for SWF Dofus maps
*
* @param <C> The cell type
* @param <M> The map type
*/
final public class MapLoader<C extends MapCell, M extends DofusMap<C>> {
final private SwfFileLoader loader;
final private DefaultMapDataSerializer serializer;
final private MapStructureCache cache;
final private MapFactory<C, M> factory;
/**
* @param loader The swf file loader
* @param serializer Map date serializer
* @param cache Cache system
* @param factory The map factory
*/
public MapLoader(SwfFileLoader loader, DefaultMapDataSerializer serializer, MapStructureCache cache, MapFactory<C, M> factory) {
this.loader = loader;
this.serializer = serializer;
this.cache = cache;
this.factory = factory;
}
/**
* Load a map from CDN
*
* @param id The map id
* @param version The map version string
* @param key The encryption key. null is the map is not encrypted
*
* @return The map instance
*
* @throws RuntimeException If the map cannot be loaded or is not found
*/
public M load(int id, String version, String key) {
final SwfMapStructure structure = cache.retrieve(id)
.filter(s -> s.version().equals(version))
.orElseGet(() -> {
try {
SwfMapStructure loaded = loader.load(id, version, key);
cache.store(loaded);
return loaded;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException("Cannot load map " + id, e);
}
})
;
return createMap(structure, key);
}
/**
* Load a map from SWF file, by URL
* The cache is not used by the method : the file is always downloaded (is needed) and parsed
*
* @param url The file URL
* @param key The encryption key. null is the map is not encrypted
*
* @return The map instance
*
* @throws IOException When cannot load the map from the URL
* @throws InterruptedException When an interruption occurs during loading the SWF file
* @throws IllegalArgumentException When an invalid map file is loaded
*/
public M loadFromUrl(URL url, String key) throws IOException, InterruptedException {
final SwfMapStructure structure = loader.load(url);
return createMap(structure, key);
}
/**
* Get the serializer for the given key
*
* @param key Key to use
*
* @return The serializer
*/
private MapDataSerializer serializer(String key) {
return key == null || key.isEmpty() ? serializer : serializer.withKey(key);
}
/**
* Create the map instance
*
* @param structure The structure
* @param key The encryption key
*
* @return The map instance
*/
private M createMap(SwfMapStructure structure, String key) {
return factory.createMap(structure, serializer(key).deserialize(structure.mapData()));
}
}