Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ public class EnrichedPackMetadata {

private String title;
private String description;

// TODO Thumbnail?

public EnrichedPackMetadata() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ public class StoryPackMetadata {
private byte[] thumbnail;
private Integer sectorSize;
private boolean nightModeAvailable = false;
private Number ageMin;
private Number ageMax;

public StoryPackMetadata() {
}
Expand All @@ -24,7 +26,7 @@ public StoryPackMetadata(String format) {
this.format = format;
}

public StoryPackMetadata(String format, String uuid, short version, String title, String description, byte[] thumbnail, Integer sectorSize, boolean nightModeAvailable) {
public StoryPackMetadata(String format, String uuid, short version, String title, String description, byte[] thumbnail, Integer sectorSize, boolean nightModeAvailable, Number ageMin, Number ageMax) {
this.format = format;
this.uuid = uuid;
this.version = version;
Expand All @@ -33,6 +35,8 @@ public StoryPackMetadata(String format, String uuid, short version, String title
this.thumbnail = thumbnail;
this.sectorSize = sectorSize;
this.nightModeAvailable = nightModeAvailable;
this.ageMin = ageMin;
this.ageMax = ageMax;
}

public String getFormat() {
Expand Down Expand Up @@ -98,4 +102,20 @@ public boolean isNightModeAvailable() {
public void setNightModeAvailable(boolean nightModeAvailable) {
this.nightModeAvailable = nightModeAvailable;
}

public Number getAgeMin() {
return ageMin;
}

public void setAgeMin(Number ageMin) {
this.ageMin = ageMin;
}

public Number getAgeMax() {
return ageMax;
}

public void setAgeMax(Number ageMax) {
this.ageMax = ageMax;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,20 +36,26 @@ public void write(StoryPack pack, OutputStream outputStream, boolean enrichedBin
if (enrichedBinaryFormat && pack.getEnriched() != null) {
writePadding(dos, Constants.BINARY_ENRICHED_METADATA_SECTOR_1_ALIGNMENT_PADDING);
writeTruncatedString(dos, pack.getEnriched().getTitle(), Constants.BINARY_ENRICHED_METADATA_TITLE_TRUNCATE);
writeTruncatedString(dos, pack.getEnriched().getDescription(), Constants.BINARY_ENRICHED_METADATA_DESCRIPTION_TRUNCATE);
writeTruncatedString(dos, pack.getEnriched().getDescription(),
Constants.BINARY_ENRICHED_METADATA_DESCRIPTION_TRUNCATE);
// TODO Thumbnail?
enrichedPackMetadataSize = Constants.BINARY_ENRICHED_METADATA_SECTOR_1_ALIGNMENT_PADDING + Constants.BINARY_ENRICHED_METADATA_TITLE_TRUNCATE*2 + Constants.BINARY_ENRICHED_METADATA_DESCRIPTION_TRUNCATE*2;
enrichedPackMetadataSize = Constants.BINARY_ENRICHED_METADATA_SECTOR_1_ALIGNMENT_PADDING
+ Constants.BINARY_ENRICHED_METADATA_TITLE_TRUNCATE * 2
+ Constants.BINARY_ENRICHED_METADATA_DESCRIPTION_TRUNCATE * 2;
}
writePadding(dos, Constants.SECTOR_SIZE - 5 - enrichedPackMetadataSize); // Skip to end of sector
writePadding(dos, Constants.SECTOR_SIZE - 5 - enrichedPackMetadataSize); // Skip to end of sector

// Count action nodes and assets (with sizes) and attribute a sector address (offset) to each
// Count action nodes and assets (with sizes) and attribute a sector address
// (offset) to each
TreeMap<SectorAddr, ActionNode> actionNodesMap = new TreeMap<>();
int nextFreeOffset = pack.getStageNodes().size();
for (StageNode stageNode : pack.getStageNodes()) {
if (stageNode.getOkTransition() != null && !actionNodesMap.containsValue(stageNode.getOkTransition().getActionNode())) {
if (stageNode.getOkTransition() != null
&& !actionNodesMap.containsValue(stageNode.getOkTransition().getActionNode())) {
actionNodesMap.put(new SectorAddr(nextFreeOffset++), stageNode.getOkTransition().getActionNode());
}
if (stageNode.getHomeTransition() != null && !actionNodesMap.containsValue(stageNode.getHomeTransition().getActionNode())) {
if (stageNode.getHomeTransition() != null
&& !actionNodesMap.containsValue(stageNode.getHomeTransition().getActionNode())) {
actionNodesMap.put(new SectorAddr(nextFreeOffset++), stageNode.getHomeTransition().getActionNode());
}
}
Expand All @@ -62,7 +68,8 @@ public void write(StoryPack pack, OutputStream outputStream, boolean enrichedBin
String assetHash = DigestUtils.sha1Hex(imageData);
if (!assetsHashes.containsKey(assetHash)) {
if (!"image/bmp".equals(image.getMimeType())) {
throw new IllegalArgumentException("Cannot write binary pack file from a compressed story pack. Uncompress the pack assets first.");
throw new IllegalArgumentException(
"Cannot write binary pack file from a compressed story pack. Uncompress the pack assets first.");
}
int imageSize = imageData.length;
int imageSectors = (imageSize / Constants.SECTOR_SIZE);
Expand All @@ -83,7 +90,8 @@ public void write(StoryPack pack, OutputStream outputStream, boolean enrichedBin
String assetHash = DigestUtils.sha1Hex(audioData);
if (!assetsHashes.containsKey(assetHash)) {
if (!"audio/x-wav".equals(audio.getMimeType())) {
throw new IllegalArgumentException("Cannot write binary pack file from a compressed story pack. Uncompress the pack assets first.");
throw new IllegalArgumentException(
"Cannot write binary pack file from a compressed story pack. Uncompress the pack assets first.");
}
int audioSize = audioData.length;
int audioSectors = (audioSize / Constants.SECTOR_SIZE);
Expand Down Expand Up @@ -164,7 +172,8 @@ public void write(StoryPack pack, OutputStream outputStream, boolean enrichedBin
int enrichedNodeMetadataSize = 0;
if (enrichedBinaryFormat && stageNode.getEnriched() != null) {
writePadding(dos, Constants.BINARY_ENRICHED_METADATA_STAGE_NODE_ALIGNMENT_PADDING);
enrichedNodeMetadataSize = Constants.BINARY_ENRICHED_METADATA_STAGE_NODE_ALIGNMENT_PADDING + writeEnrichedNodeMetadata(dos, stageNode);
enrichedNodeMetadataSize = Constants.BINARY_ENRICHED_METADATA_STAGE_NODE_ALIGNMENT_PADDING
+ writeEnrichedNodeMetadata(dos, stageNode);
}

// Skip to end of sector
Expand Down Expand Up @@ -192,19 +201,23 @@ public void write(StoryPack pack, OutputStream outputStream, boolean enrichedBin
// Write (optional) enriched node metadata
int enrichedNodeMetadataSize = 0;
if (enrichedBinaryFormat && actionNode.getEnriched() != null) {
int alignmentOverflow = 2*(actionNode.getOptions().size()) % Constants.BINARY_ENRICHED_METADATA_ACTION_NODE_ALIGNMENT;
int alignmentPadding = Constants.BINARY_ENRICHED_METADATA_ACTION_NODE_ALIGNMENT_PADDING + (alignmentOverflow > 0 ? Constants.BINARY_ENRICHED_METADATA_ACTION_NODE_ALIGNMENT - alignmentOverflow : 0);
int alignmentOverflow = 2 * (actionNode.getOptions().size())
% Constants.BINARY_ENRICHED_METADATA_ACTION_NODE_ALIGNMENT;
int alignmentPadding = Constants.BINARY_ENRICHED_METADATA_ACTION_NODE_ALIGNMENT_PADDING
+ (alignmentOverflow > 0
? Constants.BINARY_ENRICHED_METADATA_ACTION_NODE_ALIGNMENT - alignmentOverflow
: 0);
writePadding(dos, alignmentPadding);
enrichedNodeMetadataSize = alignmentPadding + writeEnrichedNodeMetadata(dos, actionNode);
}

// Skip to end of sector
writePadding(dos, Constants.SECTOR_SIZE - 2*(actionNode.getOptions().size()) - enrichedNodeMetadataSize);
writePadding(dos, Constants.SECTOR_SIZE - 2 * (actionNode.getOptions().size()) - enrichedNodeMetadataSize);
currentOffset++;
}

// Write assets (images / audio)
for (Map.Entry<AssetAddr, byte[]> assetEntry: assetsData.entrySet()) {
for (Map.Entry<AssetAddr, byte[]> assetEntry : assetsData.entrySet()) {
// First sector to write
AssetAddr assetAddr = assetEntry.getKey();
// Skip to the beginning of the sector, if needed
Expand All @@ -228,7 +241,8 @@ public void write(StoryPack pack, OutputStream outputStream, boolean enrichedBin
currentOffset += assetAddr.getSize();
}

// The Luniistore's error-checker bug is no more! No need to pad the story pack to 100000 sectors after the last action node
// The Luniistore's error-checker bug is no more! No need to pad the story pack
// to 100000 sectors after the last action node

// Write check bytes
dos.write(Constants.CHECK_BYTES, 0, Constants.CHECK_BYTES.length);
Expand Down Expand Up @@ -257,19 +271,19 @@ private int writeEnrichedNodeMetadata(DataOutputStream dos, Node node) throws IO
} else {
writePadding(dos, 4);
}
return Constants.BINARY_ENRICHED_METADATA_NODE_NAME_TRUNCATE*2 + 16 + 1 + 4;
return Constants.BINARY_ENRICHED_METADATA_NODE_NAME_TRUNCATE * 2 + 16 + 1 + 4;
}

private void writeTruncatedString(DataOutputStream dos, String str, int maxChars) throws IOException {
if (str != null) {
int strLength = Math.min(str.length(), maxChars);
dos.writeChars(str.substring(0, strLength));
int remaining = maxChars - strLength;
int remaining = maxChars - strLength;
if (remaining > 0) {
writePadding(dos, remaining*2);
writePadding(dos, remaining * 2);
}
} else {
writePadding(dos, maxChars*2);
writePadding(dos, maxChars * 2);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,20 @@ public class FsStoryPackInfos {
private short version;
private long sizeInBytes;
private boolean nightModeAvailable;
private Number ageMin;
private Number ageMax;

public FsStoryPackInfos() {
}

public FsStoryPackInfos(UUID uuid, String folderName, short version, long sizeInBytes, boolean nightModeAvailable) {
public FsStoryPackInfos(UUID uuid, String folderName, short version, long sizeInBytes, boolean nightModeAvailable, Number ageMin, Number ageMax) {
this.uuid = uuid;
this.folderName = folderName;
this.version = version;
this.sizeInBytes = sizeInBytes;
this.nightModeAvailable = nightModeAvailable;
this.ageMin = ageMin;
this.ageMax = ageMax;
}

public UUID getUuid() {
Expand Down Expand Up @@ -67,6 +71,22 @@ public void setNightModeAvailable(boolean nightModeAvailable) {
this.nightModeAvailable = nightModeAvailable;
}

public Number getAgeMin() {
return ageMin;
}

public void setAgeMin(Number ageMin) {
this.ageMin = ageMin;
}

public Number getAgeMax() {
return ageMax;
}

public void setAgeMax(Number ageMax) {
this.ageMax = ageMax;
}

@Override
public String toString() {
return "FsStoryPackInfos{" +
Expand All @@ -75,6 +95,8 @@ public String toString() {
", version=" + version +
", sizeInBytes=" + sizeInBytes +
", nightModeAvailable=" + nightModeAvailable +
", ageMin=" + ageMin +
", ageMax=" + ageMax +
'}';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,17 @@ public Optional<DatabasePackMetadata> getOfficialMetadata(String uuid) {
JsonObject localesAvailable = packMetadata.getAsJsonObject("locales_available");
String locale = localesAvailable.keySet().contains("fr_FR") ? "fr_FR" : localesAvailable.keySet().stream().findFirst().get();
JsonObject localizedInfos = packMetadata.getAsJsonObject("localized_infos").getAsJsonObject(locale);
Number ageMin = packMetadata.get("age_min").getAsNumber();
Number ageMax = packMetadata.get("age_max").getAsNumber();
return new DatabasePackMetadata(
uuid,
localizedInfos.get("title").getAsString(),
localizedInfos.get("description").getAsString(),
THUMBNAILS_STORAGE_ROOT + localizedInfos.getAsJsonObject("image").get("image_url").getAsString(),
true
true,
ageMin,
ageMax

);
});
}
Expand All @@ -122,7 +127,9 @@ public synchronized Optional<DatabasePackMetadata> getUnofficialMetadata(String
Optional.ofNullable(packMetadata.get("title")).map(JsonElement::getAsString).orElse(null),
Optional.ofNullable(packMetadata.get("description")).map(JsonElement::getAsString).orElse(null),
Optional.ofNullable(packMetadata.get("image")).map(JsonElement::getAsString).orElse(null),
false
false,
Optional.ofNullable(packMetadata.get("age_min")).map(JsonElement::getAsNumber).orElse(0),
Optional.ofNullable(packMetadata.get("age_max")).map(JsonElement::getAsNumber).orElse(0)
));
}
} catch (FileNotFoundException e) {
Expand Down
24 changes: 22 additions & 2 deletions metadata/src/main/java/studio/metadata/DatabasePackMetadata.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,20 @@ public class DatabasePackMetadata {
private String description;
private String thumbnail;
private boolean official;
private Number ageMin;
private Number ageMax;

public DatabasePackMetadata() {
}

public DatabasePackMetadata(String uuid, String title, String description, String thumbnail, boolean official) {
public DatabasePackMetadata(String uuid, String title, String description, String thumbnail, boolean official, Number ageMin, Number ageMax) {
this.uuid = uuid;
this.title = title;
this.description = description;
this.thumbnail = thumbnail;
this.official = official;
this.ageMin = ageMin;
this.ageMax = ageMax;
}

@Override
Expand All @@ -32,7 +36,9 @@ public String toString() {
", title='" + title + '\'' +
", description='" + description + '\'' +
", thumbnail='" + thumbnail + '\'' +
", official=" + official +
", official=" + official + '\'' +
", ageMin=" + ageMin + '\'' +
", ageMax=" + ageMax +
'}';
}

Expand Down Expand Up @@ -75,4 +81,18 @@ public boolean isOfficial() {
public void setOfficial(boolean official) {
this.official = official;
}

public Number getAgeMin() {
return ageMin;
}

public void setAgeMin(Number ageMin) {
this.ageMin = ageMin;
}

public Number getAgeMax() {
return ageMax;
}


}
2 changes: 2 additions & 0 deletions web-ui/javascript/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@
"author": "Marian MULLER REBEYROL",
"license": "MPL-2.0",
"private": true,
"type": "module",
"dependencies": {
"@emotion/core": "^10.0.22",
"@emotion/react": "^11.14.0",
"@emotion/styled": "^10.0.23",
"@projectstorm/react-diagrams": "^6.0.1-beta.6",
"@projectstorm/react-diagrams-defaults": "^6.0.1-beta.6",
Expand Down
20 changes: 19 additions & 1 deletion web-ui/javascript/src/components/PackLibrary.css
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
}

.header {
height: 185px;
height: 230px;
padding: 10px;
}

Expand Down Expand Up @@ -202,6 +202,24 @@
background: radial-gradient(closest-side, rgba(41, 137, 216, .8) 0%, rgba(30, 87, 153, .6) 100%);
}

.pack-grid .pack-tile .pack-age {
position: absolute;
right: 2px; bottom: 2px;
z-index: 1;
overflow: hidden;
width: 20px; height: 20px;
text-align: right;
border-radius: 10px;
}
.pack-grid .pack-tile .pack-age span {
font-size: 10px;
color: #fff;
text-align: center;
font-weight: bold; line-height: 20px;
width: 20px; display: block;
background: radial-gradient(closest-side, rgba(91, 216, 41, 0.8) 0%, rgba(91, 153, 30, 0.6) 100%);
}

.pack-grid .pack-tile .pack-ribbon {
position: absolute;
right: -5px; top: -5px;
Expand Down
Loading