Commit 4c081d78ef6e3915d0f598543661c6f2747fe949
1 parent
d2870158
Add offline support to webprefs, closes #7
Showing
6 changed files
with
451 additions
and
79 deletions
src/client/java/com/mumfrey/liteloader/client/mixin/MixinSession.java
... | ... | @@ -5,8 +5,6 @@ |
5 | 5 | */ |
6 | 6 | package com.mumfrey.liteloader.client.mixin; |
7 | 7 | |
8 | -import java.util.UUID; | |
9 | - | |
10 | 8 | import org.spongepowered.asm.mixin.Mixin; |
11 | 9 | import org.spongepowered.asm.mixin.Shadow; |
12 | 10 | import org.spongepowered.asm.mixin.injection.At; |
... | ... | @@ -30,7 +28,6 @@ public abstract class MixinSession |
30 | 28 | )) |
31 | 29 | private void generateGameProfile(CallbackInfoReturnable<GameProfile> ci) |
32 | 30 | { |
33 | - UUID uuid = EntityPlayer.getUUID(new GameProfile((UUID)null, this.getUsername())); | |
34 | - ci.setReturnValue(new GameProfile(uuid, this.getUsername())); | |
31 | + ci.setReturnValue(new GameProfile(EntityPlayer.getOfflineUUID(this.getUsername()), this.getUsername())); | |
35 | 32 | } |
36 | 33 | } | ... | ... |
src/client/java/com/mumfrey/webprefs/AbstractWebPreferences.java
0 → 100644
1 | +package com.mumfrey.webprefs; | |
2 | + | |
3 | +import java.util.Set; | |
4 | +import java.util.UUID; | |
5 | + | |
6 | +import com.mumfrey.webprefs.interfaces.IWebPreferences; | |
7 | + | |
8 | +/** | |
9 | + * Common base class for online/offline web preferences | |
10 | + */ | |
11 | +abstract class AbstractWebPreferences implements IWebPreferences | |
12 | +{ | |
13 | + /** | |
14 | + * Our UUID | |
15 | + */ | |
16 | + protected final String uuid; | |
17 | + | |
18 | + /** | |
19 | + * True if we are a private settings set | |
20 | + */ | |
21 | + protected final boolean isPrivate; | |
22 | + | |
23 | + protected final boolean isReadOnly; | |
24 | + | |
25 | + AbstractWebPreferences(UUID uuid, boolean isPrivate, boolean isReadOnly) | |
26 | + { | |
27 | + this(uuid.toString(), isPrivate, isReadOnly); | |
28 | + } | |
29 | + | |
30 | + AbstractWebPreferences(String uuid, boolean isPrivate, boolean isReadOnly) | |
31 | + { | |
32 | + this.uuid = uuid; | |
33 | + this.isPrivate = isPrivate; | |
34 | + this.isReadOnly = isReadOnly; | |
35 | + } | |
36 | + | |
37 | + void onTick() | |
38 | + { | |
39 | + // stub for subclasses | |
40 | + } | |
41 | + | |
42 | + /* (non-Javadoc) | |
43 | + * @see com.mumfrey.webprefs.interfaces.IWebPreferences#getUUID() | |
44 | + */ | |
45 | + @Override | |
46 | + public final String getUUID() | |
47 | + { | |
48 | + return this.uuid; | |
49 | + } | |
50 | + | |
51 | + /* (non-Javadoc) | |
52 | + * @see com.mumfrey.webprefs.interfaces.IWebPreferences#isPrivate() | |
53 | + */ | |
54 | + @Override | |
55 | + public final boolean isPrivate() | |
56 | + { | |
57 | + return this.isPrivate; | |
58 | + } | |
59 | + | |
60 | + /* (non-Javadoc) | |
61 | + * @see com.mumfrey.webprefs.interfaces.IWebPreferences#isReadOnly() | |
62 | + */ | |
63 | + @Override | |
64 | + public final boolean isReadOnly() | |
65 | + { | |
66 | + return this.isReadOnly; | |
67 | + } | |
68 | + | |
69 | + /* (non-Javadoc) | |
70 | + * @see com.mumfrey.webprefs.interfaces.IWebPreferences | |
71 | + * #request(java.lang.String) | |
72 | + */ | |
73 | + @Override | |
74 | + public void request(String key) | |
75 | + { | |
76 | + WebPreferences.validateKey(key); | |
77 | + } | |
78 | + | |
79 | + /* (non-Javadoc) | |
80 | + * @see com.mumfrey.webprefs.interfaces.IWebPreferences | |
81 | + * #request(java.lang.String[]) | |
82 | + */ | |
83 | + @Override | |
84 | + public void request(String... keys) | |
85 | + { | |
86 | + if (keys == null || keys.length < 1) return; | |
87 | + if (keys.length == 1) this.request(keys[0]); | |
88 | + | |
89 | + for (String key : keys) | |
90 | + { | |
91 | + this.request(key); | |
92 | + } | |
93 | + } | |
94 | + | |
95 | + /* (non-Javadoc) | |
96 | + * @see com.mumfrey.webprefs.interfaces.IWebPreferences | |
97 | + * #request(java.util.Set) | |
98 | + */ | |
99 | + @Override | |
100 | + public void request(Set<String> keys) | |
101 | + { | |
102 | + if (keys == null || keys.size() < 1) return; | |
103 | + | |
104 | + for (String key : keys) | |
105 | + { | |
106 | + this.request(key); | |
107 | + } | |
108 | + } | |
109 | + | |
110 | + /* (non-Javadoc) | |
111 | + * @see com.mumfrey.webprefs.interfaces.IWebPreferences#commit(boolean) | |
112 | + */ | |
113 | + @Override | |
114 | + public void commit(boolean force) | |
115 | + { | |
116 | + } | |
117 | + | |
118 | + /* (non-Javadoc) | |
119 | + * @see com.mumfrey.webprefs.interfaces.IWebPreferences | |
120 | + * #set(java.lang.String, java.lang.String) | |
121 | + */ | |
122 | + @Override | |
123 | + public void set(String key, String value) | |
124 | + { | |
125 | + WebPreferences.validateKey(key); | |
126 | + } | |
127 | + | |
128 | + /* (non-Javadoc) | |
129 | + * @see com.mumfrey.webprefs.interfaces.IWebPreferences | |
130 | + * #remove(java.lang.String) | |
131 | + */ | |
132 | + @Override | |
133 | + public void remove(String key) | |
134 | + { | |
135 | + this.set(key, ""); | |
136 | + } | |
137 | +} | ... | ... |
src/client/java/com/mumfrey/webprefs/DummyOfflineWebPreferences.java
0 → 100644
1 | +package com.mumfrey.webprefs; | |
2 | + | |
3 | +import java.util.UUID; | |
4 | + | |
5 | +/** | |
6 | + * No-op webpreferences set which is returned for nonlocal players when the | |
7 | + * client is running in offline mode. | |
8 | + */ | |
9 | +public class DummyOfflineWebPreferences extends AbstractWebPreferences | |
10 | +{ | |
11 | + DummyOfflineWebPreferences(UUID uuid, boolean isPrivate, boolean isReadOnly) | |
12 | + { | |
13 | + this(uuid.toString(), isPrivate, isReadOnly); | |
14 | + } | |
15 | + | |
16 | + public DummyOfflineWebPreferences(String uuid, boolean isPrivate, boolean isReadOnly) | |
17 | + { | |
18 | + super(uuid, isPrivate, isReadOnly); | |
19 | + } | |
20 | + | |
21 | + /* (non-Javadoc) | |
22 | + * @see com.mumfrey.webprefs.interfaces.IWebPreferences#poll() | |
23 | + */ | |
24 | + @Override | |
25 | + public void poll() | |
26 | + { | |
27 | + } | |
28 | + | |
29 | + /* (non-Javadoc) | |
30 | + * @see com.mumfrey.webprefs.interfaces.IWebPreferences | |
31 | + * #has(java.lang.String) | |
32 | + */ | |
33 | + @Override | |
34 | + public boolean has(String key) | |
35 | + { | |
36 | + WebPreferences.validateKey(key); | |
37 | + return false; | |
38 | + } | |
39 | + | |
40 | + /* (non-Javadoc) | |
41 | + * @see com.mumfrey.webprefs.interfaces.IWebPreferences | |
42 | + * #get(java.lang.String) | |
43 | + */ | |
44 | + @Override | |
45 | + public String get(String key) | |
46 | + { | |
47 | + WebPreferences.validateKey(key); | |
48 | + return ""; | |
49 | + } | |
50 | + | |
51 | + /* (non-Javadoc) | |
52 | + * @see com.mumfrey.webprefs.interfaces.IWebPreferences | |
53 | + * #get(java.lang.String, java.lang.String) | |
54 | + */ | |
55 | + @Override | |
56 | + public String get(String key, String defaultValue) | |
57 | + { | |
58 | + WebPreferences.validateKey(key); | |
59 | + return defaultValue; | |
60 | + } | |
61 | +} | |
0 | 62 | \ No newline at end of file | ... | ... |
src/client/java/com/mumfrey/webprefs/OfflineWebPreferences.java
0 → 100644
1 | +package com.mumfrey.webprefs; | |
2 | + | |
3 | +import java.io.File; | |
4 | +import java.io.FileReader; | |
5 | +import java.io.FileWriter; | |
6 | +import java.io.IOException; | |
7 | +import java.util.HashMap; | |
8 | +import java.util.Map; | |
9 | +import java.util.UUID; | |
10 | + | |
11 | +import com.google.gson.Gson; | |
12 | +import com.google.gson.GsonBuilder; | |
13 | +import com.mumfrey.liteloader.core.LiteLoader; | |
14 | +import com.mumfrey.webprefs.exceptions.ReadOnlyPreferencesException; | |
15 | + | |
16 | +/** | |
17 | + * Surrogate preferences returned for a local offline player, allows offline | |
18 | + * players to use the webpreferences system with preferences just being stored | |
19 | + * locally. | |
20 | + */ | |
21 | +class OfflineWebPreferences extends DummyOfflineWebPreferences | |
22 | +{ | |
23 | + /** | |
24 | + * Gson instance for serialisation/deserialisation to local JSON file | |
25 | + */ | |
26 | + private static final Gson gson = new GsonBuilder().setPrettyPrinting().create(); | |
27 | + | |
28 | + /** | |
29 | + * Maximum commit-to-disk rate in ticks | |
30 | + */ | |
31 | + private static final int COMMIT_RATE = 20 * 3; | |
32 | + | |
33 | + /** | |
34 | + * JSON file | |
35 | + */ | |
36 | + private final File store; | |
37 | + | |
38 | + /** | |
39 | + * Local KV store | |
40 | + */ | |
41 | + final Map<String, String> prefs; | |
42 | + | |
43 | + /** | |
44 | + * Tick number for write throttling | |
45 | + */ | |
46 | + private int tickNumber; | |
47 | + | |
48 | + /** | |
49 | + * Flag indicating serialisation to disk is required | |
50 | + */ | |
51 | + private boolean isDirty; | |
52 | + | |
53 | + OfflineWebPreferences(UUID uuid, boolean isPrivate, boolean isReadOnly) | |
54 | + { | |
55 | + this(uuid.toString(), isPrivate, isReadOnly); | |
56 | + } | |
57 | + | |
58 | + OfflineWebPreferences(String uuid, boolean isPrivate, boolean isReadOnly) | |
59 | + { | |
60 | + super(uuid, isPrivate, isReadOnly); | |
61 | + | |
62 | + this.store = new File(LiteLoader.getCommonConfigFolder(), String.format("%s.%sprefs.json", uuid, isPrivate ? "private" : "")); | |
63 | + this.prefs = this.loadValues(); | |
64 | + } | |
65 | + | |
66 | + @SuppressWarnings("unchecked") | |
67 | + private Map<String, String> loadValues() | |
68 | + { | |
69 | + if (this.store.isFile()) | |
70 | + { | |
71 | + FileReader reader = null; | |
72 | + | |
73 | + try | |
74 | + { | |
75 | + reader = new FileReader(this.store); | |
76 | + return OfflineWebPreferences.gson.fromJson(reader, Map.class); | |
77 | + } | |
78 | + catch (IOException ex) {} | |
79 | + finally | |
80 | + { | |
81 | + try | |
82 | + { | |
83 | + if (reader != null) reader.close(); | |
84 | + } | |
85 | + catch (IOException ex) {} | |
86 | + } | |
87 | + } | |
88 | + | |
89 | + return new HashMap<String, String>(); | |
90 | + } | |
91 | + | |
92 | + private void saveValues() | |
93 | + { | |
94 | + FileWriter writer = null; | |
95 | + | |
96 | + try | |
97 | + { | |
98 | + writer = new FileWriter(this.store); | |
99 | + OfflineWebPreferences.gson.toJson(this.prefs, writer); | |
100 | + } | |
101 | + catch (IOException ex) {} | |
102 | + finally | |
103 | + { | |
104 | + try | |
105 | + { | |
106 | + if (writer != null) writer.close(); | |
107 | + } | |
108 | + catch (IOException ex) {} | |
109 | + } | |
110 | + } | |
111 | + | |
112 | + @Override | |
113 | + void onTick() | |
114 | + { | |
115 | + if (this.tickNumber++ > OfflineWebPreferences.COMMIT_RATE && this.isDirty) | |
116 | + { | |
117 | + this.isDirty = false; | |
118 | + this.tickNumber = 0; | |
119 | + this.saveValues(); | |
120 | + } | |
121 | + } | |
122 | + | |
123 | + @Override | |
124 | + public void request(String key) | |
125 | + { | |
126 | + WebPreferences.validateKey(key); | |
127 | + if (!this.prefs.containsKey(key)) | |
128 | + { | |
129 | + this.prefs.put(key, ""); | |
130 | + } | |
131 | + } | |
132 | + | |
133 | + /* (non-Javadoc) | |
134 | + * @see com.mumfrey.webprefs.interfaces.IWebPreferences#commit(boolean) | |
135 | + */ | |
136 | + @Override | |
137 | + public void commit(boolean force) | |
138 | + { | |
139 | + this.isDirty = true; | |
140 | + } | |
141 | + | |
142 | + /* (non-Javadoc) | |
143 | + * @see com.mumfrey.webprefs.interfaces.IWebPreferences | |
144 | + * #has(java.lang.String) | |
145 | + */ | |
146 | + @Override | |
147 | + public boolean has(String key) | |
148 | + { | |
149 | + WebPreferences.validateKey(key); | |
150 | + return this.prefs.containsKey(key); | |
151 | + } | |
152 | + | |
153 | + /* (non-Javadoc) | |
154 | + * @see com.mumfrey.webprefs.interfaces.IWebPreferences | |
155 | + * #get(java.lang.String) | |
156 | + */ | |
157 | + @Override | |
158 | + public String get(String key) | |
159 | + { | |
160 | + return this.get(key, ""); | |
161 | + } | |
162 | + | |
163 | + /* (non-Javadoc) | |
164 | + * @see com.mumfrey.webprefs.interfaces.IWebPreferences | |
165 | + * #get(java.lang.String, java.lang.String) | |
166 | + */ | |
167 | + @Override | |
168 | + public String get(String key, String defaultValue) | |
169 | + { | |
170 | + WebPreferences.validateKey(key); | |
171 | + String value = this.prefs.get(key); | |
172 | + return value != null ? value : defaultValue; | |
173 | + } | |
174 | + | |
175 | + /* (non-Javadoc) | |
176 | + * @see com.mumfrey.webprefs.interfaces.IWebPreferences | |
177 | + * #set(java.lang.String, java.lang.String) | |
178 | + */ | |
179 | + @Override | |
180 | + public void set(String key, String value) | |
181 | + { | |
182 | + if (this.isReadOnly()) | |
183 | + { | |
184 | + throw new ReadOnlyPreferencesException("Preference collection for " + this.uuid + " is read-only"); | |
185 | + } | |
186 | + | |
187 | + WebPreferences.validateKV(key, value); | |
188 | + | |
189 | + this.prefs.put(key, value); | |
190 | + this.isDirty = true; | |
191 | + } | |
192 | +} | ... | ... |
src/client/java/com/mumfrey/webprefs/WebPreferences.java
... | ... | @@ -4,6 +4,7 @@ import java.util.HashMap; |
4 | 4 | import java.util.HashSet; |
5 | 5 | import java.util.Map; |
6 | 6 | import java.util.Set; |
7 | +import java.util.UUID; | |
7 | 8 | import java.util.concurrent.ConcurrentHashMap; |
8 | 9 | import java.util.regex.Pattern; |
9 | 10 | |
... | ... | @@ -12,11 +13,10 @@ import com.mumfrey.webprefs.exceptions.InvalidKeyException; |
12 | 13 | import com.mumfrey.webprefs.exceptions.InvalidValueException; |
13 | 14 | import com.mumfrey.webprefs.exceptions.ReadOnlyPreferencesException; |
14 | 15 | import com.mumfrey.webprefs.framework.RequestFailureReason; |
15 | -import com.mumfrey.webprefs.interfaces.IWebPreferences; | |
16 | 16 | import com.mumfrey.webprefs.interfaces.IWebPreferencesClient; |
17 | 17 | import com.mumfrey.webprefs.interfaces.IWebPreferencesProvider; |
18 | 18 | |
19 | -class WebPreferences implements IWebPreferences | |
19 | +class WebPreferences extends AbstractWebPreferences | |
20 | 20 | { |
21 | 21 | /** |
22 | 22 | * The update frequency to use when operating normally, this is the |
... | ... | @@ -104,18 +104,6 @@ class WebPreferences implements IWebPreferences |
104 | 104 | private final IWebPreferencesClient client; |
105 | 105 | |
106 | 106 | /** |
107 | - * Our UUID | |
108 | - */ | |
109 | - protected final String uuid; | |
110 | - | |
111 | - /** | |
112 | - * True if we are a private settings set | |
113 | - */ | |
114 | - protected final boolean isPrivate; | |
115 | - | |
116 | - protected final boolean isReadOnly; | |
117 | - | |
118 | - /** | |
119 | 107 | * Current key/value pairs |
120 | 108 | */ |
121 | 109 | protected final Map<String, String> prefs = new ConcurrentHashMap<String, String>(); |
... | ... | @@ -149,61 +137,30 @@ class WebPreferences implements IWebPreferences |
149 | 137 | private volatile int updateCheckTimer = 1; |
150 | 138 | |
151 | 139 | protected int requestTimeoutTimer = 0; |
140 | + | |
141 | + WebPreferences(IWebPreferencesProvider provider, UUID uuid, boolean isPrivate, boolean isReadOnly) | |
142 | + { | |
143 | + this(provider, uuid.toString(), isPrivate, isReadOnly); | |
144 | + } | |
152 | 145 | |
153 | 146 | WebPreferences(IWebPreferencesProvider provider, String uuid, boolean isPrivate, boolean isReadOnly) |
154 | 147 | { |
148 | + super(uuid, isPrivate, isReadOnly); | |
155 | 149 | this.provider = provider; |
156 | - this.uuid = uuid; | |
157 | - this.isPrivate = isPrivate; | |
158 | - this.isReadOnly = isReadOnly; | |
159 | 150 | this.client = new Client(); |
160 | 151 | } |
161 | 152 | |
162 | - /* (non-Javadoc) | |
163 | - * @see com.mumfrey.webprefs.interfaces.IWebPreferences#getUUID() | |
164 | - */ | |
165 | - @Override | |
166 | - public String getUUID() | |
167 | - { | |
168 | - return this.uuid; | |
169 | - } | |
170 | - | |
171 | - /* (non-Javadoc) | |
172 | - * @see com.mumfrey.webprefs.interfaces.IWebPreferences#isPrivate() | |
173 | - */ | |
174 | - @Override | |
175 | - public boolean isPrivate() | |
176 | - { | |
177 | - return this.isPrivate; | |
178 | - } | |
179 | - | |
180 | - /* (non-Javadoc) | |
181 | - * @see com.mumfrey.webprefs.interfaces.IWebPreferences#isReadOnly() | |
182 | - */ | |
183 | 153 | @Override |
184 | - public boolean isReadOnly() | |
185 | - { | |
186 | - return this.isReadOnly; | |
187 | - } | |
188 | - | |
189 | 154 | void onTick() |
190 | 155 | { |
191 | - if (this.updateCheckTimer > 0) | |
156 | + if (this.updateCheckTimer > 0 && --this.updateCheckTimer < 1) | |
192 | 157 | { |
193 | - this.updateCheckTimer--; | |
194 | - if (this.updateCheckTimer < 1) | |
195 | - { | |
196 | - this.update(); | |
197 | - } | |
158 | + this.update(); | |
198 | 159 | } |
199 | 160 | |
200 | - if (this.requestTimeoutTimer > 0) | |
161 | + if (this.requestTimeoutTimer > 0 && --this.requestTimeoutTimer < 1) | |
201 | 162 | { |
202 | - this.requestTimeoutTimer--; | |
203 | - if (this.requestTimeoutTimer < 1) | |
204 | - { | |
205 | - this.handleTimeout(); | |
206 | - } | |
163 | + this.handleTimeout(); | |
207 | 164 | } |
208 | 165 | } |
209 | 166 | |
... | ... | @@ -449,16 +406,6 @@ class WebPreferences implements IWebPreferences |
449 | 406 | } |
450 | 407 | } |
451 | 408 | |
452 | - /* (non-Javadoc) | |
453 | - * @see com.mumfrey.webprefs.interfaces.IWebPreferences | |
454 | - * #remove(java.lang.String) | |
455 | - */ | |
456 | - @Override | |
457 | - public void remove(String key) | |
458 | - { | |
459 | - this.set(key, ""); | |
460 | - } | |
461 | - | |
462 | 409 | /** |
463 | 410 | * Add a key to the current request set, the key will be requested from the |
464 | 411 | * server on the next {@link #update()} |
... | ... | @@ -563,7 +510,7 @@ class WebPreferences implements IWebPreferences |
563 | 510 | /** |
564 | 511 | * @param key |
565 | 512 | */ |
566 | - protected static final void validateKey(String key) | |
513 | + protected static void validateKey(String key) | |
567 | 514 | { |
568 | 515 | if (key == null || !WebPreferences.keyPattern.matcher(key).matches()) |
569 | 516 | { |
... | ... | @@ -575,7 +522,7 @@ class WebPreferences implements IWebPreferences |
575 | 522 | * @param key |
576 | 523 | * @param value |
577 | 524 | */ |
578 | - protected static final void validateKV(String key, String value) | |
525 | + protected static void validateKV(String key, String value) | |
579 | 526 | { |
580 | 527 | WebPreferences.validateKey(key); |
581 | 528 | ... | ... |
src/client/java/com/mumfrey/webprefs/WebPreferencesManager.java
... | ... | @@ -130,7 +130,7 @@ public final class WebPreferencesManager |
130 | 130 | /** |
131 | 131 | * All preference sets, for iteration purposes |
132 | 132 | */ |
133 | - private final List<WebPreferences> allPreferences = new LinkedList<WebPreferences>(); | |
133 | + private final List<AbstractWebPreferences> allPreferences = new LinkedList<AbstractWebPreferences>(); | |
134 | 134 | |
135 | 135 | /** |
136 | 136 | * All public preference sets, mapped by UUID |
... | ... | @@ -152,7 +152,7 @@ public final class WebPreferencesManager |
152 | 152 | { |
153 | 153 | this.provider.onTick(); |
154 | 154 | |
155 | - for (WebPreferences prefs : this.allPreferences) | |
155 | + for (AbstractWebPreferences prefs : this.allPreferences) | |
156 | 156 | { |
157 | 157 | try |
158 | 158 | { |
... | ... | @@ -164,7 +164,7 @@ public final class WebPreferencesManager |
164 | 164 | |
165 | 165 | void onJoinGame() |
166 | 166 | { |
167 | - for (WebPreferences prefs : this.allPreferences) | |
167 | + for (AbstractWebPreferences prefs : this.allPreferences) | |
168 | 168 | { |
169 | 169 | try |
170 | 170 | { |
... | ... | @@ -176,7 +176,9 @@ public final class WebPreferencesManager |
176 | 176 | |
177 | 177 | |
178 | 178 | /** |
179 | - * Get a public or private preferences collection for the local player | |
179 | + * Get a public or private preferences collection for the local player. If | |
180 | + * the game is running in offline mode, a local preference collection is | |
181 | + * returned instead. | |
180 | 182 | * |
181 | 183 | * @param privatePrefs true to fetch the player's private preferences, false |
182 | 184 | * to fetch public preferences |
... | ... | @@ -184,11 +186,21 @@ public final class WebPreferencesManager |
184 | 186 | */ |
185 | 187 | public IWebPreferences getLocalPreferences(boolean privatePrefs) |
186 | 188 | { |
187 | - return this.getPreferences(this.session.getPlayerID(), privatePrefs); | |
189 | + try | |
190 | + { | |
191 | + return this.getPreferences(this.session.getPlayerID(), privatePrefs); | |
192 | + } | |
193 | + catch (InvalidUUIDException ex) | |
194 | + { | |
195 | + UUID offlineUUID = EntityPlayer.getOfflineUUID(this.session.getUsername()); | |
196 | + return this.getOfflinePreferences(offlineUUID, privatePrefs, false, false); | |
197 | + } | |
188 | 198 | } |
189 | 199 | |
190 | 200 | /** |
191 | - * Get a public preferences collection for the specified player. | |
201 | + * Get a public preferences collection for the specified player. If the game | |
202 | + * is running in offline mode, a dummy preference collection supporting no | |
203 | + * operations is returned instead. | |
192 | 204 | * |
193 | 205 | * @param player Player to fetch preferences for |
194 | 206 | * @param privatePrefs True to fetch the player's private preferences, false |
... | ... | @@ -198,7 +210,16 @@ public final class WebPreferencesManager |
198 | 210 | */ |
199 | 211 | public IWebPreferences getPreferences(EntityPlayer player) |
200 | 212 | { |
201 | - return this.getPreferences(player, false); | |
213 | + try | |
214 | + { | |
215 | + return this.getPreferences(player, false); | |
216 | + } | |
217 | + catch (InvalidUUIDException ex) | |
218 | + { | |
219 | + String playerName = player.getName(); | |
220 | + UUID offlineUUID = EntityPlayer.getOfflineUUID(playerName); | |
221 | + return this.getOfflinePreferences(offlineUUID, false, false, !playerName.equals(this.session.getUsername())); | |
222 | + } | |
202 | 223 | } |
203 | 224 | |
204 | 225 | /** |
... | ... | @@ -279,7 +300,6 @@ public final class WebPreferencesManager |
279 | 300 | uuid = this.sanitiseUUID(uuid); |
280 | 301 | |
281 | 302 | Map<String, IWebPreferences> preferences = privatePrefs ? this.preferencesPrivate : this.preferencesPublic; |
282 | - | |
283 | 303 | IWebPreferences prefs = preferences.get(uuid); |
284 | 304 | |
285 | 305 | if (prefs == null) |
... | ... | @@ -293,6 +313,24 @@ public final class WebPreferencesManager |
293 | 313 | return prefs; |
294 | 314 | } |
295 | 315 | |
316 | + private IWebPreferences getOfflinePreferences(UUID uuid, boolean privatePrefs, boolean readOnly, boolean dummy) | |
317 | + { | |
318 | + Map<String, IWebPreferences> preferences = privatePrefs ? this.preferencesPrivate : this.preferencesPublic; | |
319 | + IWebPreferences prefs = preferences.get(uuid); | |
320 | + | |
321 | + if (prefs == null) | |
322 | + { | |
323 | + AbstractWebPreferences newPrefs = dummy | |
324 | + ? new DummyOfflineWebPreferences(uuid, privatePrefs, readOnly) | |
325 | + : new OfflineWebPreferences(uuid, privatePrefs, readOnly); | |
326 | + this.allPreferences.add(newPrefs); | |
327 | + preferences.put(uuid.toString(), newPrefs); | |
328 | + prefs = newPrefs; | |
329 | + } | |
330 | + | |
331 | + return prefs; | |
332 | + } | |
333 | + | |
296 | 334 | private String sanitiseUUID(String uuid) |
297 | 335 | { |
298 | 336 | if (uuid == null) | ... | ... |