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,8 +5,6 @@ | ||
5 | */ | 5 | */ |
6 | package com.mumfrey.liteloader.client.mixin; | 6 | package com.mumfrey.liteloader.client.mixin; |
7 | 7 | ||
8 | -import java.util.UUID; | ||
9 | - | ||
10 | import org.spongepowered.asm.mixin.Mixin; | 8 | import org.spongepowered.asm.mixin.Mixin; |
11 | import org.spongepowered.asm.mixin.Shadow; | 9 | import org.spongepowered.asm.mixin.Shadow; |
12 | import org.spongepowered.asm.mixin.injection.At; | 10 | import org.spongepowered.asm.mixin.injection.At; |
@@ -30,7 +28,6 @@ public abstract class MixinSession | @@ -30,7 +28,6 @@ public abstract class MixinSession | ||
30 | )) | 28 | )) |
31 | private void generateGameProfile(CallbackInfoReturnable<GameProfile> ci) | 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 | \ No newline at end of file | 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,6 +4,7 @@ import java.util.HashMap; | ||
4 | import java.util.HashSet; | 4 | import java.util.HashSet; |
5 | import java.util.Map; | 5 | import java.util.Map; |
6 | import java.util.Set; | 6 | import java.util.Set; |
7 | +import java.util.UUID; | ||
7 | import java.util.concurrent.ConcurrentHashMap; | 8 | import java.util.concurrent.ConcurrentHashMap; |
8 | import java.util.regex.Pattern; | 9 | import java.util.regex.Pattern; |
9 | 10 | ||
@@ -12,11 +13,10 @@ import com.mumfrey.webprefs.exceptions.InvalidKeyException; | @@ -12,11 +13,10 @@ import com.mumfrey.webprefs.exceptions.InvalidKeyException; | ||
12 | import com.mumfrey.webprefs.exceptions.InvalidValueException; | 13 | import com.mumfrey.webprefs.exceptions.InvalidValueException; |
13 | import com.mumfrey.webprefs.exceptions.ReadOnlyPreferencesException; | 14 | import com.mumfrey.webprefs.exceptions.ReadOnlyPreferencesException; |
14 | import com.mumfrey.webprefs.framework.RequestFailureReason; | 15 | import com.mumfrey.webprefs.framework.RequestFailureReason; |
15 | -import com.mumfrey.webprefs.interfaces.IWebPreferences; | ||
16 | import com.mumfrey.webprefs.interfaces.IWebPreferencesClient; | 16 | import com.mumfrey.webprefs.interfaces.IWebPreferencesClient; |
17 | import com.mumfrey.webprefs.interfaces.IWebPreferencesProvider; | 17 | import com.mumfrey.webprefs.interfaces.IWebPreferencesProvider; |
18 | 18 | ||
19 | -class WebPreferences implements IWebPreferences | 19 | +class WebPreferences extends AbstractWebPreferences |
20 | { | 20 | { |
21 | /** | 21 | /** |
22 | * The update frequency to use when operating normally, this is the | 22 | * The update frequency to use when operating normally, this is the |
@@ -104,18 +104,6 @@ class WebPreferences implements IWebPreferences | @@ -104,18 +104,6 @@ class WebPreferences implements IWebPreferences | ||
104 | private final IWebPreferencesClient client; | 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 | * Current key/value pairs | 107 | * Current key/value pairs |
120 | */ | 108 | */ |
121 | protected final Map<String, String> prefs = new ConcurrentHashMap<String, String>(); | 109 | protected final Map<String, String> prefs = new ConcurrentHashMap<String, String>(); |
@@ -149,61 +137,30 @@ class WebPreferences implements IWebPreferences | @@ -149,61 +137,30 @@ class WebPreferences implements IWebPreferences | ||
149 | private volatile int updateCheckTimer = 1; | 137 | private volatile int updateCheckTimer = 1; |
150 | 138 | ||
151 | protected int requestTimeoutTimer = 0; | 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 | WebPreferences(IWebPreferencesProvider provider, String uuid, boolean isPrivate, boolean isReadOnly) | 146 | WebPreferences(IWebPreferencesProvider provider, String uuid, boolean isPrivate, boolean isReadOnly) |
154 | { | 147 | { |
148 | + super(uuid, isPrivate, isReadOnly); | ||
155 | this.provider = provider; | 149 | this.provider = provider; |
156 | - this.uuid = uuid; | ||
157 | - this.isPrivate = isPrivate; | ||
158 | - this.isReadOnly = isReadOnly; | ||
159 | this.client = new Client(); | 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 | @Override | 153 | @Override |
184 | - public boolean isReadOnly() | ||
185 | - { | ||
186 | - return this.isReadOnly; | ||
187 | - } | ||
188 | - | ||
189 | void onTick() | 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,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 | * Add a key to the current request set, the key will be requested from the | 410 | * Add a key to the current request set, the key will be requested from the |
464 | * server on the next {@link #update()} | 411 | * server on the next {@link #update()} |
@@ -563,7 +510,7 @@ class WebPreferences implements IWebPreferences | @@ -563,7 +510,7 @@ class WebPreferences implements IWebPreferences | ||
563 | /** | 510 | /** |
564 | * @param key | 511 | * @param key |
565 | */ | 512 | */ |
566 | - protected static final void validateKey(String key) | 513 | + protected static void validateKey(String key) |
567 | { | 514 | { |
568 | if (key == null || !WebPreferences.keyPattern.matcher(key).matches()) | 515 | if (key == null || !WebPreferences.keyPattern.matcher(key).matches()) |
569 | { | 516 | { |
@@ -575,7 +522,7 @@ class WebPreferences implements IWebPreferences | @@ -575,7 +522,7 @@ class WebPreferences implements IWebPreferences | ||
575 | * @param key | 522 | * @param key |
576 | * @param value | 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 | WebPreferences.validateKey(key); | 527 | WebPreferences.validateKey(key); |
581 | 528 |
src/client/java/com/mumfrey/webprefs/WebPreferencesManager.java
@@ -130,7 +130,7 @@ public final class WebPreferencesManager | @@ -130,7 +130,7 @@ public final class WebPreferencesManager | ||
130 | /** | 130 | /** |
131 | * All preference sets, for iteration purposes | 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 | * All public preference sets, mapped by UUID | 136 | * All public preference sets, mapped by UUID |
@@ -152,7 +152,7 @@ public final class WebPreferencesManager | @@ -152,7 +152,7 @@ public final class WebPreferencesManager | ||
152 | { | 152 | { |
153 | this.provider.onTick(); | 153 | this.provider.onTick(); |
154 | 154 | ||
155 | - for (WebPreferences prefs : this.allPreferences) | 155 | + for (AbstractWebPreferences prefs : this.allPreferences) |
156 | { | 156 | { |
157 | try | 157 | try |
158 | { | 158 | { |
@@ -164,7 +164,7 @@ public final class WebPreferencesManager | @@ -164,7 +164,7 @@ public final class WebPreferencesManager | ||
164 | 164 | ||
165 | void onJoinGame() | 165 | void onJoinGame() |
166 | { | 166 | { |
167 | - for (WebPreferences prefs : this.allPreferences) | 167 | + for (AbstractWebPreferences prefs : this.allPreferences) |
168 | { | 168 | { |
169 | try | 169 | try |
170 | { | 170 | { |
@@ -176,7 +176,9 @@ public final class WebPreferencesManager | @@ -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 | * @param privatePrefs true to fetch the player's private preferences, false | 183 | * @param privatePrefs true to fetch the player's private preferences, false |
182 | * to fetch public preferences | 184 | * to fetch public preferences |
@@ -184,11 +186,21 @@ public final class WebPreferencesManager | @@ -184,11 +186,21 @@ public final class WebPreferencesManager | ||
184 | */ | 186 | */ |
185 | public IWebPreferences getLocalPreferences(boolean privatePrefs) | 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 | * @param player Player to fetch preferences for | 205 | * @param player Player to fetch preferences for |
194 | * @param privatePrefs True to fetch the player's private preferences, false | 206 | * @param privatePrefs True to fetch the player's private preferences, false |
@@ -198,7 +210,16 @@ public final class WebPreferencesManager | @@ -198,7 +210,16 @@ public final class WebPreferencesManager | ||
198 | */ | 210 | */ |
199 | public IWebPreferences getPreferences(EntityPlayer player) | 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,7 +300,6 @@ public final class WebPreferencesManager | ||
279 | uuid = this.sanitiseUUID(uuid); | 300 | uuid = this.sanitiseUUID(uuid); |
280 | 301 | ||
281 | Map<String, IWebPreferences> preferences = privatePrefs ? this.preferencesPrivate : this.preferencesPublic; | 302 | Map<String, IWebPreferences> preferences = privatePrefs ? this.preferencesPrivate : this.preferencesPublic; |
282 | - | ||
283 | IWebPreferences prefs = preferences.get(uuid); | 303 | IWebPreferences prefs = preferences.get(uuid); |
284 | 304 | ||
285 | if (prefs == null) | 305 | if (prefs == null) |
@@ -293,6 +313,24 @@ public final class WebPreferencesManager | @@ -293,6 +313,24 @@ public final class WebPreferencesManager | ||
293 | return prefs; | 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 | private String sanitiseUUID(String uuid) | 334 | private String sanitiseUUID(String uuid) |
297 | { | 335 | { |
298 | if (uuid == null) | 336 | if (uuid == null) |