Skip to content

Commit

Permalink
Fixed ZenStudio games
Browse files Browse the repository at this point in the history
  • Loading branch information
syd711 committed Nov 1, 2024
1 parent 35bfe4d commit e75da44
Show file tree
Hide file tree
Showing 9 changed files with 117 additions and 54 deletions.
19 changes: 14 additions & 5 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
## Release Notes 3.9
## Release Notes 3.9.1

## Bugfixes

- Fixed missing VPS table version resolving for Zen Studios games.
- Fixed VPS auto matching for Zen Studios games.


## Breaking Changes

### Release Notes 3.9

### Breaking Changes

- **DOF Integration**: The VPin Studio no longer supports older DOF installations that have different configuration folders for 32 and 64 bit. Instead, only the new folder structure with a shared **Config** folder is support. Please update your installation by downloading the latest DOF version from https://github.com/mjrgh/DirectOutput/releases.

## Changes
### Changes

- **PinballY Frontend**: Added support of the pinballY frontend, like others, possibility to manage tables, favorites, playlists and media, But no media search is available. (http://mjrnet.org/pinscape/PinballY.php)
- **Tables / Uploads**: Re-implemented the upload dialog for media packs and large parts of the backend here. The big disadvantage of the previous version was, that archives with a backglass and frontend media must have been uploaded twice. The new dialog detects all assets types and lets you also select/de-select them for uploading. It is also used as filter/inspection dialog for table archive uploads.
Expand Down Expand Up @@ -42,7 +51,7 @@
<img src="https://raw.githubusercontent.com/syd711/vpin-studio/main/documentation/misc/navi-buttons.png" width="100" />


## Bugfixes
### Bugfixes

- **Studio Update/Restart Error** Fixed an issue where the macOS client update process would fail to restart client. Improved macOS upgrade process. **Note: the macOS update process will work correctly AFTER this release update.**
- **System KeyEvent Handling**: Fixed key handling to avoid table deletion on DEL key press in preference panel.
Expand All @@ -54,7 +63,7 @@
- **Highscore Cards**: Fixed missing status updates. When a backglass is uploaded, the default background information for a game is refreshed too.
- **Dialog Positioning**: Dialogs are now always opened on the screen the main Studio Window is located. So only the size of a dialog is restored, not the previous position.

## VPin Mania
### VPin Mania

- Added **Delete Table Scores** button to the **Player Statistics** view. This way you can delete e.g. default highscores that have been pushed with your account name. I know this is not an optimal solution yet, but it helps users to at least clean up their own statistics. In the long run, some filtering must be provided to avoid the submission of default scores.

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 @@ -170,13 +170,30 @@ public List<VpsTableVersion> getTableFilesForFormat(String tableFormat) {
return tableFiles.stream().filter(t -> isValidTableVersion(t, tableFormat)).collect(Collectors.toList());
}

public List<VpsTableVersion> getTableFilesForFormat(List<String> tableFormat) {
return tableFiles.stream().filter(t -> isValidTableVersion(t, tableFormat)).collect(Collectors.toList());
}

private boolean isValidTableVersion(VpsTableVersion t, String tableFormat) {
if (t.getTableFormat() == null || t.getTableFormat().length() == 0) {
return true;
}
return t.getTableFormat().equals(tableFormat);
}

private boolean isValidTableVersion(VpsTableVersion t, List<String> tableFormats) {
for (String tableFormat : tableFormats) {
if (t.getTableFormat() == null || t.getTableFormat().length() == 0) {
return true;
}

if (t.getTableFormat().equals(tableFormat)) {
return true;
}
}
return false;
}

public void setTableFiles(List<VpsTableVersion> tableFiles) {
Collections.sort(tableFiles, Comparator.comparingLong((VpsTableVersion o) -> o.getUpdatedAt()));
Collections.reverse(tableFiles);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package de.mephisto.vpin.restclient.games;

import de.mephisto.vpin.connectors.vps.model.VpsFeatures;
import de.mephisto.vpin.restclient.frontend.EmulatorType;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import de.mephisto.vpin.restclient.frontend.EmulatorType;

public class GameEmulatorRepresentation {
private int id;
private String name;
Expand Down Expand Up @@ -137,6 +139,25 @@ public void setDescriptions(String descriptions) {
this.descriptions = descriptions;
}

public List<String> getVpsEmulatorFeatures() {
if (this.getEmulatorType() != null) {
switch (this.emulatorType) {
case VisualPinball: {
return Arrays.asList(VpsFeatures.VPX);
}
case FuturePinball: {
return Arrays.asList(VpsFeatures.FP);
}
case ZenFX:
case ZenFX2:
case ZenFX3: {
return Arrays.asList(VpsFeatures.FX, VpsFeatures.FX3);
}
}
}

return Arrays.asList(VpsFeatures.VPX);
}

@Override
public boolean equals(Object o) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -676,8 +676,10 @@ private synchronized boolean applyGameDetails(@NonNull Game game, boolean forceS
game.setVpsUpdates(VPSChanges.fromJson(updates));
vpsService.applyVersionInfo(game);

Optional<Highscore> highscore = this.highscoreService.getHighscore(game, forceScoreScan, EventOrigin.USER_INITIATED);
highscore.ifPresent(value -> game.setHighscoreType(value.getType() != null ? HighscoreType.valueOf(value.getType()) : null));
if (game.isVpxGame()) {
Optional<Highscore> highscore = this.highscoreService.getHighscore(game, forceScoreScan, EventOrigin.USER_INITIATED);
highscore.ifPresent(value -> game.setHighscoreType(value.getType() != null ? HighscoreType.valueOf(value.getType()) : null));
}

//run validations at the end!!!
List<ValidationState> validate = gameValidationService.validate(game, true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import de.mephisto.vpin.server.games.Game;

@Service
public class VpsAutomatcher {
public class VpsAutomatcher {
private final static Logger LOG = LoggerFactory.getLogger(VpsAutomatcher.class);

private static VpsAutomatcher instance = new VpsAutomatcher();
Expand All @@ -29,18 +29,18 @@ public static VpsAutomatcher getInstance() {

private VpsAutomatcher() {
}

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

/**
* pattern : Table (ManufacturerYear) info
*/
static Pattern filePattern1 = Pattern.compile("([^(]+)\\((.*)(\\d\\d\\d\\d)\\)(.*)" );
static Pattern filePattern1 = Pattern.compile("([^(]+)\\((.*)(\\d\\d\\d\\d)\\)(.*)");
/**
* pattern : Table (Year Manufacturer) info
*/
static Pattern filePattern2 = Pattern.compile("([^(]+)\\((\\d\\d\\d\\d)(.*)\\)(.*)");
/**
/**
* pattern : Table Year info
*/
static Pattern filePattern3 = Pattern.compile("(.*)(\\d\\d\\d\\d)(.*)");
Expand All @@ -55,20 +55,24 @@ private VpsAutomatcher() {

/**
* Match game and return a GameVpsMatch with the VPS Database mapping
*
* @return GameVpsMatch of ids
*/
public GameVpsMatch autoMatch(VPS vpsDatabase, Game game, TableInfo tableInfo, boolean checkall, boolean overwrite) {
GameVpsMatch vpsMatch = new GameVpsMatch();
vpsMatch.setGameId(game.getId());
vpsMatch.setExtTableId(game.getExtTableId());
vpsMatch.setExtTableVersionId(game.getExtTableVersionId());
vpsMatch.setVersion(game.getVersion());

String gameFileName = game.getGameFileName();
gameFileName = FilenameUtils.getBaseName(gameFileName);

autoMatch(vpsMatch, vpsDatabase, gameFileName, game.getRom(), checkall, tableInfo, overwrite);
return vpsMatch;
public GameVpsMatch autoMatch(VPS vpsDatabase, Game game, TableInfo tableInfo, boolean checkall, boolean overwrite, boolean useDisplayName) {
GameVpsMatch vpsMatch = new GameVpsMatch();
vpsMatch.setGameId(game.getId());
vpsMatch.setExtTableId(game.getExtTableId());
vpsMatch.setExtTableVersionId(game.getExtTableVersionId());
vpsMatch.setVersion(game.getVersion());

String gameFileName = game.getGameFileName();
if (useDisplayName) {
gameFileName = game.getGameDisplayName();
}
gameFileName = FilenameUtils.getBaseName(gameFileName);

autoMatch(vpsMatch, vpsDatabase, gameFileName, game.getRom(), checkall, tableInfo, overwrite);
return vpsMatch;
}

/**
Expand All @@ -83,7 +87,7 @@ public void autoMatch(GameVpsMatch vpsMatch, VPS vpsDatabase, String gameFileNam
// Step 1, decompose the filename in elements:
// tablename (manuf year) author version extra
TableNameParts parts = parseFilename(gameFileName);

String _version = null;

Matcher match = null;
Expand All @@ -96,9 +100,9 @@ public void autoMatch(GameVpsMatch vpsMatch, VPS vpsDatabase, String gameFileNam
parts.extra = StringUtils.remove(parts.extra, _version);
}
}
}
// when not found in extra, check in table name
if (_version == null) {
}
// when not found in extra, check in table name
if (_version == null) {
match = versionPattern.matcher(parts.tableName);
if (match.find()) {
_version = match.group(1);
Expand Down Expand Up @@ -126,9 +130,9 @@ public void autoMatch(GameVpsMatch vpsMatch, VPS vpsDatabase, String gameFileNam
}

String _cleanTableName = cleanTable(parts.tableName);
LOG.info("parsed : Table="+_cleanTableName + " | Manuf=" + parts.manufacturer + " | year=" + parts.year
+ " | version=" + _version + " | extra=" + parts.extra );

LOG.info("parsed : Table=" + _cleanTableName + " | Manuf=" + parts.manufacturer + " | year=" + parts.year
+ " | version=" + _version + " | extra=" + parts.extra);

//------------------------------------------------------
// Step 2, match the table elements with VPS database
Expand Down Expand Up @@ -168,7 +172,8 @@ public void autoMatch(GameVpsMatch vpsMatch, VPS vpsDatabase, String gameFileNam
// table found => update the TableId
LOG.info(gameFileName + ": matched to VPS table \"" + vpsTable.getId() + "\"");
vpsMatch.setExtTableId(vpsTable.getId());
} else {
}
else {
LOG.info(gameFileName + ": Emptied table version");
vpsMatch.setExtTableVersionId(null);
}
Expand All @@ -180,15 +185,16 @@ public void autoMatch(GameVpsMatch vpsMatch, VPS vpsDatabase, String gameFileNam

//------------------------------------------------------
// Step 3, match the elements with VPS database
if (vpsTable!=null && (StringUtils.isEmpty(vpsMatch.getExtTableVersionId()) || overwrite)) {

if (vpsTable != null && (StringUtils.isEmpty(vpsMatch.getExtTableVersionId()) || overwrite)) {

if (parts.extra == null) {
// extra being null, take table name but remove the vps table name
parts.extra = cleanTable(parts.tableName).replace(cleanTable(vpsTable.getName().toLowerCase()), "").trim();
} else {
}
else {
parts.extra = cleanChars(parts.extra);
}
}

VpsTableVersion vpsVersion = tableVersionMatcher.findVersion(vpsTable, parts.extra, _version, tableInfo);
if (vpsVersion != null) {
Expand All @@ -208,7 +214,8 @@ public void autoMatch(GameVpsMatch vpsMatch, VPS vpsDatabase, String gameFileNam
}

LOG.info("Finished auto-match for \"" + gameFileName + "\"");
} catch (Exception e) {
}
catch (Exception e) {
LOG.error("Error auto-matching table data: " + e.getMessage(), e);
}
}
Expand All @@ -223,13 +230,13 @@ public VpsTable autoMatch(VPS vpsDatabase, String filename) {

return tableMatcher.findClosest(parts.displayName, null, true, _cleanTableName, parts.manufacturer, parts.year, vpsDatabase.getTables());
}

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

private TableNameParts parseFilename(String gameFileName) {

TableNameParts parts = new TableNameParts();

parts.displayName = gameFileName
// remove reference VP10, VP9.2, VPX08....
.replaceAll("VPX?[\\d\\.]+", "")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,10 @@ public class VpsService implements InitializingBean {
* @return non null array of ids if matching was done
*/
public GameVpsMatch autoMatch(Game game, boolean overwrite) {

TableInfo tableInfo = vpxService.getTableInfo(game);

VpsAutomatcher automatcher = VpsAutomatcher.getInstance();
return automatcher.autoMatch(vpsDatabase, game, tableInfo, false, overwrite);
return automatcher.autoMatch(vpsDatabase, game, tableInfo, false, overwrite, game.isFxGame());
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import de.mephisto.vpin.restclient.frontend.VPinScreen;
import de.mephisto.vpin.restclient.games.FrontendMediaItemRepresentation;
import de.mephisto.vpin.restclient.games.FrontendMediaRepresentation;
import de.mephisto.vpin.restclient.games.GameEmulatorRepresentation;
import de.mephisto.vpin.restclient.games.GameRepresentation;
import de.mephisto.vpin.restclient.preferences.PreferenceChangeListener;
import de.mephisto.vpin.restclient.preferences.UISettings;
Expand Down Expand Up @@ -308,7 +309,9 @@ public void refreshView(Optional<GameRepresentation> g) {

VpsTable tableById = client.getVpsService().getTableById(vpsTableId);
if (tableById != null) {
refreshTableView(tableById, game.isFpGame() ? VpsFeatures.FP : VpsFeatures.VPX);
GameEmulatorRepresentation emulatorRepresentation = client.getFrontendService().getGameEmulator(game.getEmulatorId());
List<String> tableFormats = emulatorRepresentation.getVpsEmulatorFeatures();
refreshTableView(tableById, tableFormats);
if (!StringUtils.isEmpty(vpsTableVersionId)) {
VpsTableVersion version = tableById.getTableVersionById(vpsTableVersionId);
tableVersionsCombo.setValue(version);
Expand All @@ -317,10 +320,11 @@ public void refreshView(Optional<GameRepresentation> g) {
}
}

private void refreshTableView(VpsTable vpsTable, String tableFormat) {
private void refreshTableView(VpsTable vpsTable, List<String> tableFormats) {
versionAuthorsLabel.setText("-");
versionAuthorsLabel.setTooltip(new Tooltip(null));
List<VpsTableVersion> tableFiles = new ArrayList<>(vpsTable.getTableFilesForFormat(tableFormat));

List<VpsTableVersion> tableFiles = new ArrayList<>(vpsTable.getTableFilesForFormat(tableFormats));
if (!tableFiles.isEmpty()) {
tableVersionsCombo.setItems(FXCollections.emptyObservableList());
tableFiles.add(0, null);
Expand Down Expand Up @@ -452,9 +456,15 @@ public static void addSection(VBox dataRoot, String title, GameRepresentation ga
}

public static void addTablesSection(VBox dataRoot, String title, GameRepresentation game, VpsDiffTypes diffTypes, VpsTable vpsTable, boolean showUpdates, Predicate<VpsTableVersion> filterPredicate) {
final List<VpsTableVersion> tableVersions = game != null ?
vpsTable.getTableFilesForFormat(game.isFpGame() ? VpsFeatures.FP : VpsFeatures.VPX) :
vpsTable.getTableFiles();
List<VpsTableVersion> tableVersions;
if(game != null) {
GameEmulatorRepresentation emulatorRepresentation = client.getFrontendService().getGameEmulator(game.getEmulatorId());
List<String> tableFormats = emulatorRepresentation.getVpsEmulatorFeatures();
tableVersions = vpsTable.getTableFilesForFormat(tableFormats);
}
else {
tableVersions = vpsTable.getTableFiles();
}

if (tableVersions == null || tableVersions.isEmpty()) {
return;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package de.mephisto.vpin.ui.tables.dialogs;

import de.mephisto.vpin.commons.fx.DialogController;
import de.mephisto.vpin.restclient.games.*;
import de.mephisto.vpin.restclient.util.FileUtils;
import de.mephisto.vpin.commons.utils.WidgetFactory;
import de.mephisto.vpin.connectors.vps.VPS;
Expand All @@ -13,10 +14,6 @@
import de.mephisto.vpin.restclient.frontend.FrontendType;
import de.mephisto.vpin.restclient.frontend.TableDetails;
import de.mephisto.vpin.restclient.frontend.VPinScreen;
import de.mephisto.vpin.restclient.games.GameList;
import de.mephisto.vpin.restclient.games.GameListItem;
import de.mephisto.vpin.restclient.games.GameRepresentation;
import de.mephisto.vpin.restclient.games.GameVpsMatch;
import de.mephisto.vpin.restclient.highscores.HighscoreFiles;
import de.mephisto.vpin.restclient.preferences.ServerSettings;
import de.mephisto.vpin.restclient.preferences.UISettings;
Expand Down Expand Up @@ -1133,7 +1130,8 @@ private void initVpsStatus() {

private void refreshVersionsCombo(VpsTable tableById) {
if (tableById != null) {
String tableFormat = game.isFpGame() ? VpsFeatures.FP : VpsFeatures.VPX;
GameEmulatorRepresentation emulatorRepresentation = client.getFrontendService().getGameEmulator(game.getEmulatorId());
List<String> tableFormat = emulatorRepresentation.getVpsEmulatorFeatures();
List<VpsTableVersion> tableFiles = new ArrayList<>(tableById.getTableFilesForFormat(tableFormat));

if (!tableFiles.isEmpty()) {
Expand Down

0 comments on commit e75da44

Please sign in to comment.