Skip to content

Commit

Permalink
Add DevLogin support (#206)
Browse files Browse the repository at this point in the history
Co-authored-by: shartte <[email protected]>
Co-authored-by: Technici4n <[email protected]>
  • Loading branch information
3 people authored Dec 27, 2024
1 parent 77ffcc8 commit 19ebb9f
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 10 deletions.
10 changes: 10 additions & 0 deletions .github/renovate.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,16 @@
"DEFAULT_NFRT_VERSION\\s*=\\s*\"(?<currentValue>[\\d\\.\\-a-z]+)\""
],
"datasourceTemplate": "maven"
},
{
"customType": "regex",
"fileMatch": [
"RunUtils\\.java$"
],
"matchStrings": [
"String\\s+[A-Z_]+\\s*=\\s*\"(?<depName>[\\w:\\.-]+):(?<currentValue>[\\d\\.]+)(:(?<depClassifier>[a-z]+))?\"\\s*;\\s*\\/\\/\\s*renovate"
],
"datasourceTemplate": "maven"
}
]
}
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,26 @@ dependencies {
}
```

### Using Authenticated Minecraft Accounts
Minecraft runs normally use an offline user profile in a development environment.
If you want to run the game with your real user profile, you may do so using [DevLogin](https://github.com/covers1624/DevLogin) by setting
the `devLogin` property of a client run to `true`:

```groovy
neoForge {
runs {
// Add a second client run that is authenticated
clientAuth {
client()
devLogin = true
}
}
}
```

The first time you launch the authenticated run you will be asked in the console to visit https://www.microsoft.com/link and enter
the given code. More information is available on the [DevLogin readme](https://github.com/covers1624/DevLogin)

## Advanced Tips & Tricks

### Overriding Platform Libraries
Expand Down
7 changes: 7 additions & 0 deletions src/main/java/net/neoforged/moddevgradle/dsl/RunModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ public RunModel(String name, Project project, Iterable<ModModel> defaultMods) {
});

getLogLevel().convention(Level.INFO);
getDevLogin().convention(false);

// Build a nicer name for the IDE run configuration
boolean isSubProject = project.getRootProject() != project;
Expand Down Expand Up @@ -251,6 +252,12 @@ public Configuration getAdditionalRuntimeClasspathConfiguration() {
*/
public abstract Property<SourceSet> getSourceSet();

/**
* Enables <a href="https://github.com/covers1624/DevLogin">DevLogin</a> which is used to log into an
* official Minecraft account in development environments.
*/
public abstract Property<Boolean> getDevLogin();

@Override
public String toString() {
return "Run[" + getName() + "]";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
* The main plugin class.
Expand Down Expand Up @@ -510,10 +511,13 @@ static void setupRuns(Project project,
) {
var ideIntegration = IdeIntegration.of(project, branding);

// Create a configuration to resolve DevLaunch without leaking it to consumers
// Create a configuration to resolve DevLaunch and DevLogin without leaking them to consumers
var supplyDevLogin = project.provider(() -> runs.stream().anyMatch(model -> model.getDevLogin().get()));
var devLaunchConfig = project.getConfigurations().create("devLaunchConfig", spec -> {
spec.setDescription("This configuration is used to inject DevLaunch into the runtime classpaths of runs.");
spec.setDescription("This configuration is used to inject DevLaunch and optionally DevLogin into the runtime classpaths of runs.");
spec.getDependencies().add(project.getDependencyFactory().create(RunUtils.DEV_LAUNCH_GAV));
spec.getDependencies().addAllLater(supplyDevLogin.map(
supply -> supply ? List.of(project.getDependencyFactory().create(RunUtils.DEV_LOGIN_GAV)) : List.of()));
});

// Create an empty task similar to "assemble" which can be used to generate all launch scripts at once
Expand Down Expand Up @@ -628,6 +632,7 @@ private static TaskProvider<PrepareRun> setupRunInGradle(
task.getProgramArguments().set(run.getProgramArguments());
task.getJvmArguments().set(run.getJvmArguments());
task.getGameLogLevel().set(run.getLogLevel());
task.getDevLogin().set(run.getDevLogin());
task.getVersionCapabilities().set(versionCapabilities);
});
ideIntegration.runTaskOnProjectSync(prepareRunTask);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,11 +104,18 @@ abstract class PrepareRunOrTest extends DefaultTask {
@Optional
public abstract Property<VersionCapabilities> getVersionCapabilities();

/**
* The property that decides whether DevLogin is enabled.
*/
@Input
public abstract Property<Boolean> getDevLogin();

private final ProgramArgsFormat programArgsFormat;

protected PrepareRunOrTest(ProgramArgsFormat programArgsFormat) {
this.programArgsFormat = programArgsFormat;
getVersionCapabilities().convention(VersionCapabilities.latest());
getDevLogin().convention(false);
}

protected abstract UserDevRunType resolveRunType(UserDevConfig userDevConfig);
Expand Down Expand Up @@ -153,8 +160,19 @@ public void prepareRun() throws IOException {
runConfig = resolveRunType(userDevConfig);
}

writeJvmArguments(runConfig);
writeProgramArguments(runConfig);
var mainClass = resolveMainClass(runConfig);
var devLogin = getDevLogin().get();

var sysProps = new LinkedHashMap<String, String>();

// When DevLogin is used, we swap out the main class with the DevLogin one, and add the actual main class as a system property
if (devLogin && mainClass != null) {
sysProps.put("devlogin.launch_target", mainClass);
mainClass = RunUtils.DEV_LOGIN_MAIN_CLASS;
}

writeJvmArguments(runConfig, sysProps);
writeProgramArguments(runConfig, mainClass);
}

private UserDevConfig loadUserDevConfig(File userDevFile) {
Expand Down Expand Up @@ -208,7 +226,7 @@ private UserDevConfig getSimulatedUserDevConfigForVanilla() {
return new UserDevConfig(runTypes);
}

private void writeJvmArguments(UserDevRunType runConfig) throws IOException {
private void writeJvmArguments(UserDevRunType runConfig, Map<String, String> additionalProperties) throws IOException {
var lines = new ArrayList<String>();

lines.addAll(getInterpolatedJvmArgs(runConfig));
Expand Down Expand Up @@ -238,7 +256,9 @@ private void writeJvmArguments(UserDevRunType runConfig) throws IOException {
addSystemProp(prop.getKey(), propValue, lines);
}

for (var entry : getSystemProperties().get().entrySet()) {
additionalProperties.putAll(getSystemProperties().get());

for (var entry : additionalProperties.entrySet()) {
addSystemProp(entry.getKey(), entry.getValue(), lines);
}

Expand All @@ -250,10 +270,9 @@ private void writeJvmArguments(UserDevRunType runConfig) throws IOException {
);
}

private void writeProgramArguments(UserDevRunType runConfig) throws IOException {
private void writeProgramArguments(UserDevRunType runConfig, @Nullable String mainClass) throws IOException {
var lines = new ArrayList<String>();

var mainClass = resolveMainClass(runConfig);
if (mainClass != null) {
lines.add("# Main Class");
lines.add(mainClass);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,10 @@ final class RunUtils {
private RunUtils() {
}

public static String DEV_LAUNCH_GAV = "net.neoforged:DevLaunch:1.0.1";
public static String DEV_LAUNCH_MAIN_CLASS = "net.neoforged.devlaunch.Main";
public static final String DEV_LAUNCH_GAV = "net.neoforged:DevLaunch:1.0.1"; // renovate
public static final String DEV_LAUNCH_MAIN_CLASS = "net.neoforged.devlaunch.Main";
public static final String DEV_LOGIN_GAV = "net.covers1624:DevLogin:0.1.0.5"; // renovate
public static final String DEV_LOGIN_MAIN_CLASS = "net.covers1624.devlogin.DevLogin";

public static String escapeJvmArg(String arg) {
var escaped = arg.replace("\\", "\\\\").replace("\"", "\\\"");
Expand Down
4 changes: 4 additions & 0 deletions testproject/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ neoForge {
client()
programArguments.addAll('--username', 'Dev2')
}
clientAuth {
client()
devLogin = true
}
gradleOnlyClient {
client()
programArguments.addAll('--username', 'Dev3')
Expand Down

0 comments on commit 19ebb9f

Please sign in to comment.