-
Notifications
You must be signed in to change notification settings - Fork 39
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
Fix path loading when working with optifine data. #94
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,13 +9,11 @@ | |
import org.apache.logging.log4j.LogManager; | ||
import org.apache.logging.log4j.Logger; | ||
|
||
import java.util.ArrayList; | ||
import java.util.HashSet; | ||
import java.util.Set; | ||
import java.util.*; | ||
|
||
/** Helps with internal stuff, all you need to know is that it keeps track of the renderers and files */ | ||
public class CemFairy{ | ||
private static final Set<EntityType<? extends Entity>> supportedEntities = new HashSet<>(); | ||
private static final Set<EntityType<? extends Entity>> supportedEntities = new HashSet<>(); | ||
private static final Set<BlockEntityType<? extends BlockEntity>> supportedBlockEntities = new HashSet<>(); | ||
private static final Set<String> supportedOthers = new HashSet<>(); | ||
private static final Logger LOGGER = LogManager.getLogger("Custom Entity Models"); | ||
|
@@ -55,33 +53,65 @@ public static String getEntityNameFromId(Identifier identifier){ | |
String id = identifier.toString(); | ||
return id.substring(id.lastIndexOf("/") + 1, id.lastIndexOf(".jem")); | ||
} | ||
|
||
//file stuff | ||
public static Identifier transformPath(String path, Identifier location){ | ||
//relative to current folder | ||
if(path.startsWith("./")){ | ||
return new Identifier(location.getNamespace(), location.getPath().substring(0, location.getPath().lastIndexOf('/') + 1) + path.substring(2)); | ||
|
||
public static Identifier transformPath(String path, Identifier location) { | ||
var pathChunks = new LinkedList<>(Arrays.asList(path.split("/"))); | ||
var firstChunk = pathChunks.get(0); | ||
|
||
// Remove the file name from the location path or trailing slash | ||
var locationPath = new LinkedList<>(Arrays.asList(location.getPath().split("/"))); | ||
var lastLocationChunk = locationPath.get(locationPath.size() - 1); | ||
if (lastLocationChunk.equals("") || lastLocationChunk.matches(".+\\..+")) { | ||
locationPath.remove(locationPath.size() - 1); | ||
location = new Identifier(location.getNamespace(), String.join("/", locationPath)); | ||
} | ||
//go up a folder | ||
else if(path.startsWith("../")){ | ||
return transformPath(path.substring(3), new Identifier(location.getNamespace(), location.getPath().substring(0, location.getPath().lastIndexOf('/')))); | ||
|
||
// Uses a explicit namespace | ||
if (pathChunks.get(0).contains(":")) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Handles loading from namespaces other than 'minecraft' or 'dorianpb'. |
||
var nsAndChunk = firstChunk.split(":"); | ||
location = new Identifier(nsAndChunk[0], ""); | ||
firstChunk = nsAndChunk[1]; | ||
pathChunks.set(0, firstChunk); | ||
} | ||
//relative to "assets/dorianpb/cem" | ||
else if(path.startsWith("~/")){ | ||
return new Identifier("dorianpb", "cem/" + path.substring(2)); | ||
|
||
// Specifies an absolute path | ||
if (firstChunk.equals("")) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If the path had a leading slash then start the path from the root of the location namespace. |
||
location = new Identifier(location.getNamespace(), ""); | ||
pathChunks.removeFirst(); | ||
} | ||
//relative to "assets/namespace/" | ||
else if(path.chars().filter(ch -> ch == ':').count() == 1){ | ||
String path2 = path.substring(path.indexOf(":") + 1); | ||
if(path2.startsWith("/")){ | ||
path2 = path2.replaceFirst("/", ""); | ||
} | ||
return transformPath(path2, new Identifier(path.substring(0, path.indexOf(":")), "")); | ||
|
||
// Specifies a relative path | ||
else if (firstChunk.equals(".")) { | ||
pathChunks.removeFirst(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If the path is relative (starts with "./") then the path starts from the path of location. |
||
} | ||
//look for file in current folder | ||
else{ | ||
return new Identifier(location.getNamespace(), location.getPath().substring(0, location.getPath().lastIndexOf('/') + 1) + path); | ||
|
||
// Specifies an optifine folder or dorianpb folder path | ||
else if (firstChunk.equals("~")) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a bit tricky here. If we are loading a resource from within the "dorianpb" namespace, then we follow the existing logic for paths starting with " |
||
pathChunks.removeFirst(); | ||
location = location.getNamespace().equals("dorianpb") | ||
? new Identifier(location.getNamespace(), "cem") | ||
: new Identifier("minecraft", "optifine"); | ||
} | ||
|
||
// Move the location path up for each ".." chunk at the beginning of the path | ||
else if (firstChunk.equals("..")) { | ||
var basePathChunks = new LinkedList<>(Arrays.asList(location.getPath().split("/"))); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If the path starts with parent folder path expressions ("..") we walk up the path from parent to parent for each ".." chunk in the path. This is the expected behavior when working with *nix path expressions. |
||
while (pathChunks.get(0).equals("..")) { | ||
if (basePathChunks.size() == 0) { break; } | ||
pathChunks.removeFirst(); | ||
basePathChunks.remove(basePathChunks.size() - 1); | ||
} | ||
location = new Identifier(location.getNamespace(), String.join("/", basePathChunks)); | ||
|
||
// Deal with Optifine's rather strange pathing behaviour | ||
// When Optifine loads a texture path does not contain "/", it loads relative to the file. | ||
} else if (location.getNamespace().equals("minecraft") && path.contains("/")) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This was added because of some nuts behavior I found in the optifine source code. If a path contains slashes then the path is assumed to be relative to the namespace root. I assume you don't want to do with for cem data in the "dorianpb" namespace, so I only perform the path adjustment if we are in the "minecraft" namespace. |
||
location = new Identifier(location.getNamespace(), ""); | ||
} | ||
|
||
// Finalize the transformed path as a new Identifier | ||
if (!location.getPath().equals("")) { pathChunks.addFirst(location.getPath()); } | ||
return new Identifier(location.getNamespace(), String.join("/", pathChunks)); | ||
} | ||
|
||
public static void postReadError(Exception exception, Identifier id){ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Strips the end of the location path if it is a path to a file with extension, and removes trailing stashes.