Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Emulator support #749

Draft
wants to merge 70 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
820fb7b
Rating column
syd711 Jan 31, 2025
bf594bd
Rating column
syd711 Jan 31, 2025
9259673
Rating column
syd711 Jan 31, 2025
36da893
Rating column
syd711 Jan 31, 2025
a26e17f
vps comments
syd711 Jan 31, 2025
f9aa844
vps comments
syd711 Jan 31, 2025
72f41ca
Reverted sidebar layout
syd711 Feb 1, 2025
c037242
Screen Manager Start
syd711 Feb 1, 2025
1f9d283
qa
syd711 Feb 2, 2025
c168513
screen preview
syd711 Feb 2, 2025
c1e901a
table patching
syd711 Feb 2, 2025
2db9e82
table patching
syd711 Feb 2, 2025
cc47313
table patching
syd711 Feb 2, 2025
6ac7f62
https://github.com/syd711/vpin-studio/issues/672
syd711 Feb 2, 2025
bc3c306
https://github.com/syd711/vpin-studio/issues/672
syd711 Feb 2, 2025
327a0e3
first draft for new screens service
leprinco Feb 3, 2025
65637fb
fix dof when no api key setup
leprinco Feb 3, 2025
26b2fc9
move screens client services back in FrontendServiceClient
leprinco Feb 3, 2025
37618ea
simplify Res Generator window
leprinco Feb 3, 2025
6645169
Merge branch 'main' into leprinco/screens-service
leprinco Feb 4, 2025
516d496
Merge branch 'rc3.13' into leprinco/screens-service
leprinco Feb 4, 2025
aef4bc9
main merge
syd711 Feb 4, 2025
56c9e78
main merge
syd711 Feb 4, 2025
5b56e87
Merge pull request #739 from syd711/leprinco/screens-service
syd711 Feb 4, 2025
5eda0f9
IScored fine tuning
leprinco Feb 4, 2025
c5a3bed
reverted changes for screens
syd711 Feb 4, 2025
bc05f27
better error handling
syd711 Feb 4, 2025
6e135c1
Merge branch 'rc3.13' of https://github.com/syd711/vpin-studio into r…
leprinco Feb 4, 2025
0870690
Merge branch 'rc3.13' of https://github.com/syd711/vpin-studio into r…
syd711 Feb 4, 2025
b06d60e
fix vPinballX.ini parse
leprinco Feb 4, 2025
a0877fa
main merge
syd711 Feb 4, 2025
955c1ca
fix issue on start
leprinco Feb 4, 2025
5614e3c
Merge branch 'rc3.13' of https://github.com/syd711/vpin-studio into r…
syd711 Feb 5, 2025
8c66dad
3.13 merge
syd711 Feb 5, 2025
6e1ef34
ScreenInfo to MonitorInfo
syd711 Feb 5, 2025
01b85ce
Table overview : Add disabled colors on new columns (playlists, ratin…
leprinco Feb 5, 2025
a3164be
Merge branch 'rc3.13' of https://github.com/syd711/vpin-studio into r…
leprinco Feb 5, 2025
b24f430
Feature Flag Screen Manager
syd711 Feb 5, 2025
860bdb1
screen manager dev branch merge
syd711 Feb 5, 2025
79e45fc
screen manager dev branch merge
syd711 Feb 5, 2025
627e853
Switching to horizontal design
syd711 Feb 5, 2025
735596c
Fixed refresh
syd711 Feb 6, 2025
7b33d6a
Fixed refresh
syd711 Feb 6, 2025
05d3739
Webhooks
syd711 Feb 6, 2025
b58a69a
Playlist icon previews
syd711 Feb 6, 2025
540e356
Webhooks
syd711 Feb 7, 2025
f8f39cf
Webhooks
syd711 Feb 7, 2025
cd99d47
Webhooks
syd711 Feb 8, 2025
54f12c4
Webhooks
syd711 Feb 8, 2025
4e6f0b1
main merge
syd711 Feb 8, 2025
bf300d4
Webhooks
syd711 Feb 8, 2025
e30d374
Webhooks
syd711 Feb 8, 2025
593ea6d
Fixed screens
syd711 Feb 9, 2025
f2ea548
Fixed Asset Manager for Playlists
syd711 Feb 9, 2025
136c524
Webhooks
syd711 Feb 9, 2025
e3037b9
main merge
syd711 Feb 13, 2025
27acbdc
qa
syd711 Feb 14, 2025
9e49fb5
Emulator Manager
syd711 Feb 14, 2025
37810d8
Emulator Manager
syd711 Feb 14, 2025
cf62a8c
Emulator Manager
syd711 Feb 14, 2025
ca51708
qa
syd711 Feb 15, 2025
33b5c3c
EmulatorService
syd711 Feb 15, 2025
2aaa952
Emulator Manager
syd711 Feb 15, 2025
a978107
Emulator Manager
syd711 Feb 15, 2025
20d686d
Emulator Manager
syd711 Feb 15, 2025
af52eab
Emulator Manager
syd711 Feb 15, 2025
c7e2f8c
Emulator Manager
syd711 Feb 16, 2025
2a5ae89
Emulator Manager
syd711 Feb 16, 2025
f199b31
Emulator Manager
syd711 Feb 16, 2025
93658d2
Emulator Manager
syd711 Feb 16, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
248 changes: 11 additions & 237 deletions RELEASE_NOTES.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion config/connection.properties
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#Wed Jan 29 18:54:29 CET 2025
#Thu Feb 13 22:22:00 CET 2025
connection1.ip=192.168.178.187
connection1.mac_address=
connection1.magic_packet_port=9
Expand Down
2 changes: 1 addition & 1 deletion resources/vpsdb.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
Expand All @@ -29,8 +30,6 @@ public class IScored {

private static ObjectMapper objectMapper;

private final static String BASE_URL = "https://www.iscored.info";

static {
objectMapper = new ObjectMapper();
objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
Expand All @@ -40,6 +39,11 @@ public class IScored {

private static Map<String, GameRoom> cache = new HashMap<>();

//fixme implement proper check
public static boolean isIscoredGameRoomUrl(String dashboardUrl) {
return true; //dashboardUrl != null && dashboardUrl.toLowerCase().contains("iscored.info");
}

public static GameRoom getGameRoom(@NonNull String url) {
if (!cache.containsKey(url)) {
cache.put(url, loadGameRoom(url));
Expand All @@ -53,26 +57,18 @@ public static void invalidate() {

public static GameRoom loadGameRoom(@NonNull String url) {
try {

long start = System.currentTimeMillis();
if (!url.toLowerCase().startsWith(BASE_URL.toLowerCase())) {
throw new UnsupportedOperationException("Invalid iscored.info URL \"" + url + "\"");
if (!isIscoredGameRoomUrl(url)) {
throw new UnsupportedOperationException("Invalid gameroom URL \"" + url + "\"");
}

String userName = null;
if (url.contains("&")) {
Map<String, String> params = splitQuery(new URL(url));
if (!params.containsKey("user")) {
throw new UnsupportedOperationException("Invalid iscored.info URL \"" + url + "\"");
}

userName = params.get("user");
}
else {
userName = url.substring(BASE_URL.length() + 1).trim();
}
// parse and align room URL
URL roomurl = new URL(url);
String baseUrl = getBaseURL(roomurl);
Map<String, String> params = getBaseParams(roomurl);

String readUrl = BASE_URL + "/publicCommands.php?c=getRoomInfo&user=" + userName;
URL gameRoomURL = new URL(readUrl);
URL gameRoomURL = composeURL(baseUrl, params, "/publicCommands.php?c=getRoomInfo");
GameRoom gameRoom = new GameRoom();
gameRoom.setUrl(url);

Expand All @@ -84,16 +80,16 @@ public static GameRoom loadGameRoom(@NonNull String url) {
gameRoom.setSettings(gameRoomModel.getSettings());
gameRoom.setName(gameRoomModel.getSettings().getRoomName());

URL gamesInfoURL = new URL(BASE_URL + "/publicCommands.php?c=getAllGames&roomID=" + gameRoomModel.getRoomID());
URL gamesInfoURL = composeURL(baseUrl, params, "/publicCommands.php?c=getAllGames&roomID=" + gameRoomModel.getRoomID());
if (gameRoom.getSettings().isApiReadingEnabled()) {
LOG.info("READ API enabled, using API endpoint for game infos.");
gamesInfoURL = new URL(BASE_URL + "/api/" + userName);
gamesInfoURL = composeURL(baseUrl, params, "/api/" + params.get("user"));
}

String gamesInfo = loadJson(gamesInfoURL);
GameModel[] games = objectMapper.readValue(gamesInfo, GameModel[].class);

URL gameScoresURL = new URL(BASE_URL + "/publicCommands.php?c=getScores2&roomID=" + gameRoomModel.getRoomID());
URL gameScoresURL = composeURL(baseUrl, params, "/publicCommands.php?c=getScores2&roomID=" + gameRoomModel.getRoomID());
String scoresInfo = loadJson(gameScoresURL);
Score[] scores = objectMapper.readValue(scoresInfo, Score[].class);

Expand All @@ -112,7 +108,7 @@ public static GameRoom loadGameRoom(@NonNull String url) {
gameRoom.getGames().add(game);
}

LOG.info("Loaded game room for user '" + userName + "', found " + gameRoom.getGames().size() + " games. (" + (System.currentTimeMillis() - start) + "ms)");
LOG.info("Loaded game room from URL '" + url + "', found " + gameRoom.getGames().size() + " games. (" + (System.currentTimeMillis() - start) + "ms)");
return gameRoom;
}
}
Expand All @@ -123,16 +119,49 @@ public static GameRoom loadGameRoom(@NonNull String url) {
return null;
}

private static String getBaseURL(URL roomUrl) {
String baseUrl = roomUrl.getProtocol() + "://" + roomUrl.getAuthority();
if (baseUrl.endsWith("/")) {
baseUrl = baseUrl.substring(0, baseUrl.length() - 1);
}
return baseUrl;
}

private static Map<String, String> getBaseParams(URL roomUrl) {
Map<String, String> params = splitQuery(roomUrl);
if (!params.containsKey("user")) {
String userName = roomUrl.getPath();
if (userName.startsWith("/")) {
userName = userName.substring(1);
}
if (userName == null || userName.isEmpty()) {
throw new UnsupportedOperationException("Invalid gameroom URL (no user provider) \"" + roomUrl + "\"");
}
params.put("user", userName);
}
return params;
}

private static URL composeURL(String baseUrl, Map<String, String> params, String path) throws MalformedURLException {
String newUrl = baseUrl + path;
for (Map.Entry<String, String> entry : params.entrySet()) {
newUrl += (newUrl.contains("?") ? "&" : "?") + entry.getKey();
if (entry.getValue() != null) {
newUrl += "=" + entry.getValue();
}
}
return new URL(newUrl);
}

private static String loadJson(URL url) {
BufferedInputStream in = null;
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
in = new BufferedInputStream(conn.getInputStream());
IOUtils.copy(in, out);

in.close();

try (BufferedInputStream in = new BufferedInputStream(conn.getInputStream())) {
IOUtils.copy(in, out);
}

out.flush();
out.close();
conn.disconnect();
Expand All @@ -149,10 +178,16 @@ private static String loadJson(URL url) {
public static Map<String, String> splitQuery(URL url) {
Map<String, String> query_pairs = new LinkedHashMap<String, String>();
String query = url.getQuery();
String[] pairs = query.split("&");
for (String pair : pairs) {
int idx = pair.indexOf("=");
query_pairs.put(URLDecoder.decode(pair.substring(0, idx), StandardCharsets.UTF_8), URLDecoder.decode(pair.substring(idx + 1), StandardCharsets.UTF_8));
if (query != null) {
String[] pairs = query.split("&");
for (String pair : pairs) {
int idx = pair.indexOf("=");
if (idx < 0) {
query_pairs.put(URLDecoder.decode(pair, StandardCharsets.UTF_8), null);
} else {
query_pairs.put(URLDecoder.decode(pair.substring(0, idx), StandardCharsets.UTF_8), URLDecoder.decode(pair.substring(idx + 1), StandardCharsets.UTF_8));
}
}
}
return query_pairs;
}
Expand Down Expand Up @@ -186,7 +221,7 @@ public static IScoredResult submitScore(GameRoom gameRoom, IScoredGame game, Str


LOG.info("Submitting iScored score \"" + playerName + "/" + playerInitials + " [" + highscore + "]\" to game \"" + game.getName() + "\" of game room \"" + gameRoom.getName() + "\"");
BufferedInputStream in = null;
HttpURLConnection conn = null;
try {
String name = playerName;
try {
Expand All @@ -203,19 +238,23 @@ public static IScoredResult submitScore(GameRoom gameRoom, IScoredGame game, Str
name = URLEncoder.encode(name, StandardCharsets.UTF_8);

ByteArrayOutputStream out = new ByteArrayOutputStream();
URL url = new URL(BASE_URL + "/publicCommands.php?c=addScore&name=" + name + "&game=" + game.getId() + "&score=" + highscore + "&wins=undefined&losses=undefined&roomID=" + gameRoom.getRoomID());
HttpURLConnection conn = (HttpURLConnection) url.openConnection();

URL roomurl = new URL(gameRoom.getUrl());
String baseUrl = getBaseURL(roomurl);
Map<String, String> params = getBaseParams(roomurl);

URL url = composeURL(baseUrl, params, "/publicCommands.php?c=addScore&name=" + name + "&game=" + game.getId() + "&score=" + highscore + "&wins=undefined&losses=undefined&roomID=" + gameRoom.getRoomID());

conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST"); // PUT is another valid option
conn.setDoOutput(true);

in = new BufferedInputStream(conn.getInputStream());
IOUtils.copy(in, out);

in.close();
try (BufferedInputStream in = new BufferedInputStream(conn.getInputStream())) {
IOUtils.copy(in, out);
}

out.flush();
out.close();
conn.disconnect();

LOG.info("Submitted new highscore to iScored game room \"" + gameRoom.getName() + "\": name=" + name + ", game=" + game.getId() + ", score=" + highscore);
result.setMessage("Submitted new highscore to iScored game room \"" + gameRoom.getName() + "\": name=" + name + ", game=" + game.getId() + ", score=" + highscore);
Expand All @@ -233,6 +272,11 @@ public static IScoredResult submitScore(GameRoom gameRoom, IScoredGame game, Str
LOG.error("Failed to submit iScored highscore: " + e.getMessage(), e);
result.setMessage("Failed to submit iScored highscore: " + e.getMessage());
}
finally {
if (conn != null) {
conn.disconnect();
}
}
return result;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ public class VpsTable implements VPSEntity {
private int year;
private long updatedAt;

//----------- Custom fields
private String comment;


//------------------
public VpsTableVersion getTableVersionById(String extTableVersionId) {
if (this.tableFiles != null && extTableVersionId != null) {
Expand Down Expand Up @@ -58,6 +62,15 @@ public List<String> getAvailableTableFormats() {

//------------------


public String getComment() {
return comment;
}

public void setComment(String comment) {
this.comment = comment;
}

public List<VpsTutorialUrls> getTutorialFiles() {
return tutorialFiles;
}
Expand Down

This file was deleted.

Loading