Skip to content

Commit 090c59f

Browse files
author
Made By IToncek
committed
Progress
1 parent 99e8d32 commit 090c59f

14 files changed

Lines changed: 416 additions & 35 deletions

File tree

api/src/main/java/space/itoncek/trailcompass/client/api/HideAndSeekAPI.java

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
import java.io.IOException;
99
import java.time.ZonedDateTime;
1010
import java.util.Objects;
11+
import java.util.logging.Level;
12+
import java.util.logging.Logger;
1113

1214
import okhttp3.MediaType;
1315
import okhttp3.OkHttpClient;
@@ -25,13 +27,19 @@ public abstract class HideAndSeekAPI {
2527
final OkHttpClient client = new OkHttpClient();
2628
private WebSocket ws;
2729

30+
public HideAndSeekAPI() {
31+
Logger.getLogger(OkHttpClient.class.getName()).setLevel(Level.FINE);
32+
}
33+
34+
public abstract void sendLogMessage(String message);
35+
public abstract void sendExceptionMessage(String message, Throwable t);
2836
public abstract HideAndSeekConfig getConfig();
2937
public abstract void saveConfig(HideAndSeekConfig cfg);
3038

3139
public ServerValidity checkValidity() throws IOException {
3240
Response response = get(getConfig().base_url + "/");
33-
boolean successful = response.isSuccessful();
34-
if(!successful) return ServerValidity.NOT_FOUND;
41+
if(response == null || !response.isSuccessful()) return ServerValidity.NOT_FOUND;
42+
3543
assert response.body() != null;
3644
String version = response.body().string();
3745
response.close();
@@ -75,6 +83,7 @@ public LoginResponse login() throws IOException, JSONException {
7583
cfg.jwt_token = new JSONObject(res.body().string()).getString("token");
7684
saveConfig(cfg);
7785
} catch (IOException | JSONException e) {
86+
sendExceptionMessage("Unable to auth",e);
7887
return LoginResponse.UNABLE_TO_AUTH;
7988
}
8089
res.close();
@@ -97,6 +106,14 @@ public boolean amIAdmin() throws IOException {
97106
}
98107
}
99108

109+
public boolean amIHider() throws IOException {
110+
HideAndSeekConfig cfg = getConfig();
111+
try(Response authd = getAuthd(cfg.base_url + "/uac/amIHider")) {
112+
assert (authd != null ? authd.body() : null) != null && authd.isSuccessful();
113+
return Boolean.parseBoolean(authd.body().string());
114+
}
115+
}
116+
100117
public @Nullable String myName() throws IOException {
101118
HideAndSeekConfig cfg = getConfig();
102119
try(Response authd = getAuthd(cfg.base_url + "/uac/myName")) {
@@ -146,15 +163,20 @@ public boolean cycleHider() throws IOException {
146163
}
147164
}
148165

149-
public Response get(String url) throws IOException {
150-
Request request = new Request.Builder()
151-
.url(url)
152-
.build();
153-
154-
return client.newCall(request).execute();
166+
public @Nullable Response get(String url) throws IOException {
167+
try {
168+
Request request = new Request.Builder()
169+
.url(url)
170+
.build();
171+
172+
return client.newCall(request).execute();
173+
} catch (IllegalArgumentException e) {
174+
sendLogMessage("Unable to parse the URL!");
175+
return null;
176+
}
155177
}
156178

157-
public Response post(String url, String json) throws IOException {
179+
public @Nullable Response post(String url, String json) throws IOException {
158180
RequestBody body = RequestBody.create(json, JSON);
159181
Request request = new Request.Builder()
160182
.url(url)

app/src/main/AndroidManifest.xml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,16 @@
3232
android:name=".hideandseek.configurator.ConfiguratorActivity"
3333
android:exported="false" />
3434
<activity
35-
android:name=".hideandseek.ui.AwaitStartActivity"
35+
android:name=".hideandseek.generic_ui.AwaitStartActivity"
3636
android:exported="false" />
3737
<activity
38-
android:name=".hideandseek.ui.LoginActivity"
38+
android:name=".hideandseek.generic_ui.LoginActivity"
3939
android:exported="false" />
4040
<activity
41-
android:name=".hideandseek.ui.MapView"
41+
android:name=".hideandseek.seeker_ui.SeekerMapView"
42+
android:exported="false" />
43+
<activity
44+
android:name=".hideandseek.hider_ui.HiderMapView"
4245
android:exported="false" />
4346
<activity
4447
android:name=".mainmenu.MainMenuActivity"

app/src/main/java/space/itoncek/trailcompass/app/hideandseek/api/HideAndSeekAPIFactory.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,16 @@ public HideAndSeekAPIFactory(File filesDir) {
2222
}
2323
public HideAndSeekAPI generateHideAndSeekAPI() {
2424
return new HideAndSeekAPI() {
25+
@Override
26+
public void sendLogMessage(String message) {
27+
Log.d("HideAndSeekApi",message);
28+
}
29+
30+
@Override
31+
public void sendExceptionMessage(String message, Throwable t) {
32+
Log.w("HideAndSeekApi",message,t);
33+
}
34+
2535
@Override
2636
public @Nullable HideAndSeekConfig getConfig() {
2737
File cfile = new File(filesDir + "/config.dat");

app/src/main/java/space/itoncek/trailcompass/app/hideandseek/ui/AwaitStartActivity.java renamed to app/src/main/java/space/itoncek/trailcompass/app/hideandseek/generic_ui/AwaitStartActivity.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package space.itoncek.trailcompass.app.hideandseek.ui;
1+
package space.itoncek.trailcompass.app.hideandseek.generic_ui;
22

33
import static android.view.View.GONE;
44
import static android.view.View.VISIBLE;
@@ -33,6 +33,7 @@
3333
import space.itoncek.trailcompass.app.R;
3434
import space.itoncek.trailcompass.app.hideandseek.api.HideAndSeekAPIFactory;
3535
import space.itoncek.trailcompass.app.hideandseek.configurator.ConfiguratorActivity;
36+
import space.itoncek.trailcompass.app.hideandseek.seeker_ui.SeekerMapView;
3637
import space.itoncek.trailcompass.client.api.GameState;
3738
import space.itoncek.trailcompass.client.api.HideAndSeekAPI;
3839

@@ -67,7 +68,7 @@ private void updateTime() {
6768
if(!showTimer) return;
6869

6970
if(Duration.between(ZonedDateTime.now(),gameStartTime).isNegative()) {
70-
Intent i = new Intent(c, MapView.class);
71+
Intent i = new Intent(c, SeekerMapView.class);
7172
startActivity(i);
7273
finish();
7374
ses.shutdown();
@@ -165,7 +166,7 @@ private void updateAppDisplay() {
165166
loadMeta();
166167
});
167168
case INGAME,MOVE_PERIOD -> {
168-
Intent i = new Intent(c, MapView.class);
169+
Intent i = new Intent(c, SeekerMapView.class);
169170
startActivity(i);
170171
finish();
171172
}

app/src/main/java/space/itoncek/trailcompass/app/hideandseek/ui/LoginActivity.java renamed to app/src/main/java/space/itoncek/trailcompass/app/hideandseek/generic_ui/LoginActivity.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package space.itoncek.trailcompass.app.hideandseek.ui;
1+
package space.itoncek.trailcompass.app.hideandseek.generic_ui;
22

33
import static space.itoncek.trailcompass.app.utils.RunnableUtils.runOnBackgroundThread;
44
import static space.itoncek.trailcompass.client.api.LoginResponse.UNABLE_TO_CONNECT;
@@ -63,26 +63,24 @@ protected void onCreate(Bundle savedInstanceState) {
6363

6464
CountDownLatch cdl = new CountDownLatch(1);
6565
AtomicReference<LoginResponse> login = new AtomicReference<>();
66-
Thread t = new Thread(() -> {
66+
runOnBackgroundThread(() -> {
6767
runOnUiThread(()->mProgressLabel.setText(String.format(getString(R.string.login_started) , api.getConfig().username)));
6868
try {
6969
login.set(api.login());
7070
} catch (IOException | JSONException e) {
7171
Log.e(LoginActivity.class.getName(), getResources().getText(R.string.login_unable_to_connect).toString(), e);
72-
runOnBackgroundThread(()->Toast.makeText(this, getResources().getText(R.string.login_unable_to_connect), Toast.LENGTH_LONG).show());
72+
runOnUiThread(()->Toast.makeText(this, getResources().getText(R.string.login_unable_to_connect), Toast.LENGTH_LONG).show());
7373
login.set(UNABLE_TO_CONNECT);
7474
}
7575
cdl.countDown();
7676
});
77-
t.start();
7877

7978
try {
8079
cdl.await();
8180
} catch (InterruptedException e) {
8281
Log.d(LoginActivity.class.getName(), "Interrupted", e);
8382
}
8483

85-
Toast.makeText(this, login.get().name(), Toast.LENGTH_SHORT).show();
8684
switch (login.get()) {
8785
case UNABLE_TO_CONNECT -> {
8886
runOnUiThread(()->mProgressLabel.setText(R.string.login_unable_to_connect));

app/src/main/java/space/itoncek/trailcompass/app/hideandseek/ui/MainmenuHideandseekLogin.java renamed to app/src/main/java/space/itoncek/trailcompass/app/hideandseek/generic_ui/MainmenuHideandseekLogin.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package space.itoncek.trailcompass.app.hideandseek.ui;
1+
package space.itoncek.trailcompass.app.hideandseek.generic_ui;
22

33
import static com.google.common.hash.Hashing.sha512;
44

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
package space.itoncek.trailcompass.app.hideandseek.hider_ui;
2+
3+
import static android.view.View.GONE;
4+
import static android.view.View.VISIBLE;
5+
6+
import static space.itoncek.trailcompass.app.utils.RunnableUtils.runOnBackgroundThread;
7+
8+
import android.content.Intent;
9+
import android.os.Bundle;
10+
import android.util.Log;
11+
import android.widget.TextView;
12+
13+
import androidx.activity.EdgeToEdge;
14+
import androidx.appcompat.app.AppCompatActivity;
15+
import androidx.core.graphics.Insets;
16+
import androidx.core.view.ViewCompat;
17+
import androidx.core.view.WindowInsetsCompat;
18+
19+
import org.mapsforge.core.util.Parameters;
20+
import org.mapsforge.map.android.graphics.AndroidGraphicFactory;
21+
import org.mapsforge.map.android.util.AndroidUtil;
22+
import org.mapsforge.map.datastore.MapDataStore;
23+
import org.mapsforge.map.layer.cache.TileCache;
24+
import org.mapsforge.map.layer.renderer.TileRendererLayer;
25+
import org.mapsforge.map.reader.MapFile;
26+
import org.mapsforge.map.rendertheme.internal.MapsforgeThemes;
27+
28+
import java.io.File;
29+
import java.io.IOException;
30+
import java.util.concurrent.CountDownLatch;
31+
import java.util.concurrent.atomic.AtomicBoolean;
32+
33+
import space.itoncek.trailcompass.app.R;
34+
import space.itoncek.trailcompass.app.hideandseek.api.HideAndSeekAPIFactory;
35+
import space.itoncek.trailcompass.app.hideandseek.seeker_ui.SeekerMapView;
36+
import space.itoncek.trailcompass.client.api.HideAndSeekAPI;
37+
38+
public class HiderMapView extends AppCompatActivity {
39+
private HideAndSeekAPI api;
40+
private org.mapsforge.map.android.view.MapView mapView;
41+
File mapfile;
42+
43+
@Override
44+
protected void onCreate(Bundle savedInstanceState) {
45+
super.onCreate(savedInstanceState);
46+
EdgeToEdge.enable(this);
47+
setContentView(R.layout.activity_hide_mapview);
48+
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
49+
Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
50+
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
51+
return insets;
52+
});
53+
AndroidGraphicFactory.createInstance(getApplication());
54+
55+
mapfile = new File(getCacheDir() + "/map.map");
56+
mapView = findViewById(R.id.map_mapview);
57+
api = new HideAndSeekAPIFactory(getFilesDir()).generateHideAndSeekAPI();
58+
59+
if(amIHider()) {
60+
showAdminView();
61+
setUsername();
62+
setupTimer();
63+
setupButtons();
64+
openMap();
65+
} else {
66+
Intent i = new Intent(this, SeekerMapView.class);
67+
startActivity(i);
68+
finish();
69+
}
70+
}
71+
72+
private boolean amIHider() {
73+
AtomicBoolean result = new AtomicBoolean(false);
74+
CountDownLatch cdl = new CountDownLatch(1);
75+
runOnBackgroundThread(()-> {
76+
try {
77+
result.set(api.amIHider());
78+
cdl.countDown();
79+
} catch (IOException e) {
80+
Log.e(HiderMapView.class.getName(),"Unable to determine if I'm a hider or not",e);
81+
}
82+
});
83+
try {
84+
cdl.await();
85+
} catch (InterruptedException e) {
86+
throw new RuntimeException(e);
87+
}
88+
return result.get();
89+
}
90+
91+
private void setupButtons() {
92+
findViewById(R.id.map_resetButton).setOnClickListener((c)-> {
93+
setUsername();
94+
showAdminView();
95+
setupTimer();
96+
});
97+
}
98+
99+
// TODO)) Create timer handler!
100+
private void setupTimer() {
101+
102+
}
103+
104+
private void setUsername() {
105+
Thread t = new Thread(()-> {
106+
try {
107+
String name = api.myName();
108+
runOnUiThread(()-> ((TextView)findViewById(R.id.map_username)).setText(name));
109+
} catch (IOException e) {
110+
Log.e(HiderMapView.class.getName(), "Unable to contact the main server", e);
111+
}
112+
});
113+
t.start();
114+
}
115+
116+
private void showAdminView() {
117+
Thread t = new Thread(()-> {
118+
try {
119+
if (api.amIAdmin()) {
120+
runOnUiThread(()->findViewById(R.id.map_switchToSettings).setVisibility(VISIBLE));
121+
} else {
122+
runOnUiThread(()->findViewById(R.id.map_switchToSettings).setVisibility(GONE));
123+
}
124+
} catch (IOException e) {
125+
Log.e(HiderMapView.class.getName(), "Unable to contact the main server", e);
126+
}
127+
});
128+
t.start();
129+
}
130+
131+
private void openMap() {
132+
mapView.setClickable(true);
133+
mapView.getMapScaleBar().setVisible(true);
134+
mapView.setBuiltInZoomControls(true);
135+
136+
Parameters.NUMBER_OF_THREADS = 8;
137+
Parameters.ANTI_ALIASING = true;
138+
Parameters.PARENT_TILES_RENDERING = Parameters.ParentTilesRendering.SPEED;
139+
140+
TileCache tileCache = AndroidUtil.createTileCache(this, "mapcache",
141+
mapView.getModel().displayModel.getTileSize(), 1f,
142+
mapView.getModel().frameBufferModel.getOverdrawFactor());
143+
144+
MapDataStore mapDataStore = new MapFile(mapfile);
145+
TileRendererLayer tileRendererLayer = new TileRendererLayer(tileCache, mapDataStore,
146+
mapView.getModel().mapViewPosition, AndroidGraphicFactory.INSTANCE);
147+
tileRendererLayer.setCacheTileMargin(1);
148+
tileRendererLayer.setCacheZoomMinus(1);
149+
tileRendererLayer.setCacheZoomPlus(2);
150+
tileRendererLayer.setXmlRenderTheme(MapsforgeThemes.OSMARENDER);
151+
152+
mapView.getLayerManager().getLayers().add(tileRendererLayer);
153+
154+
mapView.setCenter(mapDataStore.startPosition());
155+
mapView.setZoomLevel(mapDataStore.startZoomLevel());
156+
}
157+
}

0 commit comments

Comments
 (0)