Coder Social home page Coder Social logo

ignite's Introduction

Ignite Logo

Ignite is a Mixin loader for Spigot/Paper.


Build Status MIT License Discord Maven Central Sonatype Nexus (Snapshots)

Install

Download the ignite.jar from the releases page.

Place the ignite.jar into the same directory with your Minecraft Server jar (i.e paper.jar, spigot.jar or server.jar).

Run your original start command, but replace the normal server jar with ignite.jar. If you are using Java 8 you will need to add -javaagent:./ignite.jar to your start command.

If Ignite cannot start your server, you may need to add additional startup flags. See the Advanced Section below for more information. If you're still confused, be sure to ask for help.

The mods can then be placed into the mods directory that will be created.

Making a Mod

The ignite-mod-template is a template you can use to start a project for Paper without needing to do all the setup yourself.

To depend on the Ignite API in order to create your mod, you will need to add the following to your buildscript:

Gradle

repositories {
  mavenCentral()
  maven {
    url = "https://repo.spongepowered.org/maven/"
  }
}

dependencies {
  compileOnly "space.vectrix.ignite:ignite-api:1.0.1"
  compileOnly "org.spongepowered:mixin:0.8.5"
  compileOnly "io.github.llamalad7:mixinextras-common:0.3.5"
}

Maven

<repositories>
  <repository>
    <url>https://repo.spongepowered.org/maven/</url>
  </repository>
</repositories>

<dependencies>
  <dependency>
    <groupId>space.vectrix.ignite</groupId>
    <artifactId>ignite-api</artifactId>
    <version>1.0.1</version>
  </dependency>
  <dependency>
    <groupId>org.spongepowered</groupId>
    <artifactId>mixin</artifactId>
    <version>0.8.5</version>
  </dependency>
  <dependency>
    <groupId>io.github.llamalad7</groupId>
    <artifactId>mixinextras-common</artifactId>
    <version>0.3.5</version>
  </dependency>
</dependencies>

Note: To support custom mappings you should check out ignite-mod-template if you're running Paper. For Spigot check out Pacifist Remapper.

Configuring your Mod

Your mod will require a ignite.mod.json in order to be located as a mod. The ignite.mod.json provides the metadata needed to load your mixins and access wideners.

Example ignite.mod.json:

{
  "id": "example",
  "version": "1.0.0",
  "mixins": [
    "mixins.example.core.json"
  ],
  "wideners": [
    "example.accesswidener"
  ]
}

The mods will need to be placed in the directory the launcher will be targeting to load.

Using Mixins

The Mixin configuration files will need to be available in your mods binary in order to be loaded. The name of each configuration file should be added to the mixins section in your ignite.mod.json, or alternatively could be added to your jar manifest.

Mixin Specification

Using Access Wideners

The Access Wideners configuration files will need to be available in your mods binary in order to be loaded. The name of each configuration file should be added to the wideners section in your ignite.mod.json, or alternatively could be added to your jar manifest with the AccessWidener key.

Warning: Access wideners should only be used in situations where Mixin will not work!

Access Widener Specification

Advanced Usage

Ignite has some properties that can be set on startup to change the launch target, mod directory and more. The following could be added to your startup script:

  • The game locator service to use. (e.g -Dignite.locator=dummy)
  • The path to the server jar. (e.g -Dignite.jar=./server.jar)
  • The classpath to the server entry point. (e.g -Dignite.target=org.bukkit.craftbukkit.Main)
  • The directory ignite libraries will be located. (e.g -Dignite.libraries=./libraries)
  • The directory ignite mods will be located. (e.g -Dignite.mods=./mods)

Game Locators

Game locators provide platform specific modifications to the launch process. In some cases where the platform cannot be automatically detected, these flags can set the information it needs to launch.

The following targets could use the following flags:

  • Paper (1.18+):

    • Service name: paper (e.g -Dignite.locator=paper)
    • Extra properties:
      • The path to the paperclip jar. (e.g -Dignite.paper.jar=./paper.jar)
      • The classpath to the paperclip entry point. (e.g -Dignite.paper.target=io.papermc.paperclip.Paperclip)
      • The minecraft server version paperclip will be patching. (e.g -Dignite.paper.version=1.20.4)
  • Spigot (1.18+):

    • Service name: spigot (e.g -Dignite.locator=spigot)
    • Extra properties:
      • Tge path to the spigot bundler directory. (e.g -Dignite.spigot.bundler=./bundler)
      • The path to the spigot bootstrap jar. (e.g -Dignite.spigot.jar=./spigot.jar)
      • The classpath to the spigot bootstrap entry point. (e.g -Dignite.spigot.target=org.bukkit.craftbukkit.bootstrap.Main)
      • The spigot version it will be using. (e.g -Dignite.spigot.version=1.20.4-R0.1-SNAPSHOT)
  • Paper Legacy:

    • Service name: legacy_paper (e.g -Dignite.locator=legacy_paper)
    • Extra properties:
      • The path to the paperclip jar. (e.g -Dignite.paper.jar=./paper.jar)
      • The classpath to the paperclip entry point. (e.g -Dignite.paper.target=io.papermc.paperclip.Paperclip)
      • The minecraft server version paperclip will be patching. (e.g -Dignite.paper.version=1.12.2)

Building

Note: If you do not have Gradle installed then use ./gradlew for Unix systems or Git Bash and gradlew.bat for Windows systems in place of any 'gradle' command.

In order to build Ignite you simply need to run the gradle build command. You can find the compiled JAR file in ./build/libs/ named 'ignite.jar'.

Inspiration

This project has many parts inspired by the following projects:

ignite's People

Contributors

aromaa avatar buepas avatar dependabot[bot] avatar kujoumolean avatar renovate-bot avatar renovate[bot] avatar vectrixdevelops avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

ignite's Issues

Further Examples

It may help further expose and explain the project to have more examples, and potentially making some fully working projects that use this. I can come up with a few but if anyone else has ideas they want to contribute I don't mind sinking a bit of time into them as well.

Paper Problem

I'm running Ignite V0.4.0.
I use ignite boot paper for the use mixin.
but this has some problem with ignite work with paper.

Paper 1.16 has the tab complete with colored tip.

-- But ignite can't adapt it.Even can't use tab.
-- Maybe we need log4j2 plugin or other to Compatible with paper.
-- (In some case,console don't output anything, cursor on the last output up,Maybe is the windows cmd's problem)

Debug.log output a lot about Minecraft Packet to the Client.

-- such as ([Netty Server IO #1/DEBUG] [net.minecraft.server.v1_16_R3.PacketEncoder]: OUT: [PLAY:70] net.minecraft.server.v1_16_R3.PacketPlayOutEntityVelocity)
-- It can make log file very big.

Log format problem

-- [186月2021 17:08:23] [main/DEBUG] [mixin]: Initialising Mixin Platform Manager
-- In Chinese,We generally format time like "yyyy MM dd",but output print like "dd mm月 yyyy"
-- This is not a serious problem.

Sorry for the grammar problem,I'm not good at english.
The most serious problem is packet debug output,It seems make the network lag,But tps is 20.
Mixin is very compatible with paper(currently)
Thanks for ignite.

1.18.1 paper java.lang.NoSuchMethodError

[03:20:53 ERROR]: Encountered an unexpected exception
java.lang.NoSuchMethodError: org/yaml/snakeyaml/DumperOptions.setProcessComments(Z)V (loaded from by cpw.mods.modlauncher.TransformingClassLoader@90734ff0) called from class org.bukkit.configuration.file.YamlConfiguration (loaded from by cpw.mods.modlauncher.TransformingClassLoader@90734ff0).
at org.bukkit.configuration.file.YamlConfiguration.saveToString(YamlConfiguration.java:76) ~[?:?]
at org.bukkit.configuration.file.FileConfiguration.save(FileConfiguration.java:65) ~[?:?]
at org.bukkit.craftbukkit.v1_18_R1.CraftServer.saveConfig(CraftServer.java:395) ~[?:git-Paper-205]
at org.bukkit.craftbukkit.v1_18_R1.CraftServer.(CraftServer.java:333) ~[?:git-Paper-205]
at net.minecraft.server.players.PlayerList.(PlayerList.java:160) ~[?:git-Paper-205]
at net.minecraft.server.dedicated.DedicatedPlayerList.(DedicatedPlayerList.java:15) ~[?:git-Paper-205]
at net.minecraft.server.dedicated.DedicatedServer.e(DedicatedServer.java:212) ~[?:git-Paper-205]
at net.minecraft.server.MinecraftServer.w(MinecraftServer.java:1202) [?:git-Paper-205]
at net.minecraft.server.MinecraftServer.lambda$spin$0(MinecraftServer.java:317) [?:git-Paper-205]
at net.minecraft.server.MinecraftServer$$Lambda$4091/0x0000000002f9f230.run(Unknown Source) [?:git-Paper-205]
at java.lang.Thread.run(Unknown Source) [?:?]
[03:20:53 WARN] [oshi.util.FileUtil]: Configuration conflict: there is more than one oshi.architecture.properties file on the classpath
[03:20:53 ERROR]: This crash report has been saved to: D:\test.\crash-reports\crash-2022-02-21_03.20.53-server.tx
crash-2022-02-21_03.20.53-server.txt
t
I don't have any mods or plugins installed and this error occurs when I load ignite

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

This repository currently has no open or pending branches.

Detected dependencies

github-actions
.github/workflows/build.yml
  • actions/checkout v4
  • actions/setup-java v4
  • gradle/gradle-build-action v3
gradle
gradle.properties
settings.gradle.kts
  • org.gradle.toolchains.foojay-resolver-convention 0.8.0
build.gradle.kts
api/build.gradle.kts
build-logic/settings.gradle.kts
build-logic/build.gradle.kts
build-logic/src/main/kotlin/ignite.base-conventions.gradle.kts
build-logic/src/main/kotlin/ignite.launcher-conventions.gradle.kts
build-logic/src/main/kotlin/ignite.parent-conventions.gradle.kts
build-logic/src/main/kotlin/ignite.publish-conventions.gradle.kts
gradle/libs.versions.toml
  • org.jetbrains:annotations 24.1.0
  • org.tinylog:tinylog-api 2.7.0
  • org.tinylog:tinylog-impl 2.7.0
  • net.fabricmc:access-widener 2.1.0
  • org.ow2.asm:asm 9.7
  • org.ow2.asm:asm-analysis 9.7
  • org.ow2.asm:asm-commons 9.7
  • org.ow2.asm:asm-tree 9.7
  • org.ow2.asm:asm-util 9.7
  • net.fabricmc:sponge-mixin 0.14.0+mixin.0.8.6
  • io.github.llamalad7:mixinextras-common 0.3.6
  • com.google.code.gson:gson 2.11.0
  • ca.stellardrift:stylecheck 0.1
  • io.github.gradle-nexus:publish-plugin 2.0.0
  • com.github.johnrengelman:shadow 8.1.1
  • com.diffplug.spotless:spotless-plugin-gradle 6.25.0
  • com.puppycrawl.tools:checkstyle 10.17.0
launcher/build.gradle.kts
gradle-wrapper
gradle/wrapper/gradle-wrapper.properties
  • gradle 8.8

  • Check this box to trigger a request for Renovate to run again on this repository

Velocity game locator

Velocity could do with a game locator to remove the complexity from setting all the flags manually.

error load a mod for mixin

ModEngine 131 -> final String widenerFiles = resource.getManifest().getMainAttributes().getValue(IgniteConstants.ACCESS_WIDENER);

Exception in thread "main" java.lang.NullPointerException
at space.vectrix.ignite.applaunch.mod.ModEngine.loadTransformers(ModEngine.java:131)
at space.vectrix.ignite.applaunch.handler.IgniteTransformationService.runScan(IgniteTransformationService.java:64)
at cpw.mods.modlauncher.TransformationServiceDecorator.runScan(TransformationServiceDecorator.java:114)
at cpw.mods.modlauncher.TransformationServicesHandler.lambda$runScanningTransformationServices$8(TransformationServicesHandler.java:115)
at java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:267)
at java.util.HashMap$ValueSpliterator.forEachRemaining(HashMap.java:1628)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472)
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
at cpw.mods.modlauncher.TransformationServicesHandler.runScanningTransformationServices(TransformationServicesHandler.java:116)
at cpw.mods.modlauncher.TransformationServicesHandler.initializeTransformationServices(TransformationServicesHandler.java:63)
at cpw.mods.modlauncher.Launcher.run(Launcher.java:76)
at cpw.mods.modlauncher.Launcher.main(Launcher.java:66)
at space.vectrix.ignite.applaunch.IgniteBootstrap.run(IgniteBootstrap.java:165)
at space.vectrix.ignite.applaunch.IgniteBootstrap.main(IgniteBootstrap.java:93)

Build fails on task ignite-api:signArchives

When attempting to build release 0.6.0 using gradlew build on Windows with AdoptOpenJDK 8 and 16, I'm getting the following error:

> Task :ignite-api:signArchives FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':ignite-api:signArchives'.
> Cannot perform signing task ':ignite-api:signArchives' because it has no configured signatory

I suspect that this has something to do with signing keys not being set up locally. I'm expecting the main branch to either build without additional actions, or the README to contain information about how to set this up in the building section.

Unable to properly boot Paper 1.19.4

[19Mar2023 14:35:29] [main/INFO]: Ignite Launcher v0.8.1
[19Mar2023 14:35:29] [main/INFO]: Preparing ModLauncher with arguments [--launchTarget, ignitelaunch]
[19Mar2023 14:35:29] [main/INFO]: ModLauncher running: args [--launchTarget, ignitelaunch]
[19Mar2023 14:35:29] [main/INFO]: ModLauncher 8.1.3+8.1.3+main-8.1.x.c94d18ec starting: java version 17.0.4.1 by Azul Systems, Inc.
[19Mar2023 14:35:29] [main/INFO]: SpongePowered MIXIN Subsystem Version=0.8.5 Source=file:/C:/Users/Molean/IdeaProjects/IsletopiaIgnite/servers/server1/ignite-launcher.jar Service=ModLauncher Env=SERVER
[19Mar2023 14:35:29] [main/INFO]: Located 1 mod(s).
[19Mar2023 14:35:29] [main/INFO]: Applied transformer(s).
[19Mar2023 14:35:29] [main/INFO]: Launching target 'ignitelaunch' with arguments []
[19Mar2023 14:35:29] [main/INFO]: Loading [[email protected]].
[19Mar2023 14:35:30] [main/WARN]: Configuration conflict: there is more than one oshi.properties file on the classpath: [jar:file:/C:/Users/Molean/IdeaProjects/IsletopiaIgnite/servers/server1/libraries/com/github/oshi/oshi-core/6.2.2/oshi-core-6.2.2.jar!/oshi.properties, jar:file:/C:/Users/Molean/IdeaProjects/IsletopiaIgnite/servers/server1/libraries/com/github/oshi/oshi-core/6.2.2/oshi-core-6.2.2.jar!/oshi.properties]
[19Mar2023 14:35:30] [main/WARN]: Configuration conflict: there is more than one oshi.architecture.properties file on the classpath: [jar:file:/C:/Users/Molean/IdeaProjects/IsletopiaIgnite/servers/server1/libraries/com/github/oshi/oshi-core/6.2.2/oshi-core-6.2.2.jar!/oshi.architecture.properties, jar:file:/C:/Users/Molean/IdeaProjects/IsletopiaIgnite/servers/server1/libraries/com/github/oshi/oshi-core/6.2.2/oshi-core-6.2.2.jar!/oshi.architecture.properties]
[19Mar2023 14:35:34] [main/INFO]: Environment: authHost='https://authserver.mojang.com', accountsHost='https://api.mojang.com', sessionHost='https://sessionserver.mojang.com', servicesHost='https://api.minecraftservices.com', name='PROD'
[19Mar2023 14:35:35] [main/INFO]: [STDERR]: java.lang.NoSuchMethodError: 'com.mojang.serialization.DataResult com.mojang.serialization.DataResult.error(java.util.function.Supplier)'
[19Mar2023 14:35:35] [main/INFO]: [STDERR]: 	at com.mojang.serialization.Dynamic.lambda$get$11(Dynamic.java:117)
[19Mar2023 14:35:35] [main/INFO]: [STDERR]: 	at com.mojang.serialization.DataResult.lambda$flatMap$10(DataResult.java:138)
[19Mar2023 14:35:35] [main/INFO]: [STDERR]: 	at com.mojang.datafixers.util.Either$Left.map(Either.java:38)
[19Mar2023 14:35:35] [main/INFO]: [STDERR]: 	at com.mojang.serialization.DataResult.flatMap(DataResult.java:136)
[19Mar2023 14:35:35] [main/INFO]: [STDERR]: 	at com.mojang.serialization.Dynamic.get(Dynamic.java:114)
[19Mar2023 14:35:35] [main/INFO]: [STDERR]: 	at com.mojang.serialization.OptionalDynamic.lambda$get$0(OptionalDynamic.java:76)
[19Mar2023 14:35:35] [main/INFO]: [STDERR]: 	at com.mojang.serialization.DataResult.lambda$flatMap$10(DataResult.java:138)
[19Mar2023 14:35:35] [main/INFO]: [STDERR]: 	at com.mojang.datafixers.util.Either$Left.map(Either.java:38)
[19Mar2023 14:35:35] [main/INFO]: [STDERR]: 	at com.mojang.serialization.DataResult.flatMap(DataResult.java:136)
[19Mar2023 14:35:35] [main/INFO]: [STDERR]: 	at com.mojang.serialization.OptionalDynamic.get(OptionalDynamic.java:76)
[19Mar2023 14:35:35] [main/INFO]: [STDERR]: 	at net.minecraft.world.level.GameRules.lambda$loadFromTag$5(GameRules.java:145)
[19Mar2023 14:35:35] [main/INFO]: [STDERR]: 	at com.google.common.collect.RegularImmutableMap.forEach(RegularImmutableMap.java:292)
[19Mar2023 14:35:35] [main/INFO]: [STDERR]: 	at net.minecraft.world.level.GameRules.a(GameRules.java:144)
[19Mar2023 14:35:35] [main/INFO]: [STDERR]: 	at net.minecraft.world.level.GameRules.<init>(GameRules.java:117)
[19Mar2023 14:35:35] [main/INFO]: [STDERR]: 	at net.minecraft.world.level.WorldSettings.a(WorldSettings.java:29)
[19Mar2023 14:35:35] [main/INFO]: [STDERR]: 	at net.minecraft.world.level.storage.Convertable.lambda$levelSummaryReader$5(Convertable.java:277)
[19Mar2023 14:35:35] [main/INFO]: [STDERR]: 	at net.minecraft.world.level.storage.Convertable.a(Convertable.java:196)
[19Mar2023 14:35:35] [main/INFO]: [STDERR]: 	at net.minecraft.world.level.storage.Convertable$ConversionSession.c(Convertable.java:446)
[19Mar2023 14:35:35] [main/INFO]: [STDERR]: 	at net.minecraft.server.Main.main(Main.java:201)
[19Mar2023 14:35:35] [main/INFO]: [STDERR]: 	at org.bukkit.craftbukkit.Main.main(Main.java:309)
[19Mar2023 14:35:35] [main/INFO]: [STDERR]: 	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[19Mar2023 14:35:35] [main/INFO]: [STDERR]: 	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
[19Mar2023 14:35:35] [main/INFO]: [STDERR]: 	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[19Mar2023 14:35:35] [main/INFO]: [STDERR]: 	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
[19Mar2023 14:35:35] [main/INFO]: [STDERR]: 	at space.vectrix.ignite.launch.IgniteLaunch.launch(IgniteLaunch.java:69)
[19Mar2023 14:35:35] [main/INFO]: [STDERR]: 	at space.vectrix.ignite.launch.IgniteLaunch.main(IgniteLaunch.java:46)
[19Mar2023 14:35:35] [main/INFO]: [STDERR]: 	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[19Mar2023 14:35:35] [main/INFO]: [STDERR]: 	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
[19Mar2023 14:35:35] [main/INFO]: [STDERR]: 	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[19Mar2023 14:35:35] [main/INFO]: [STDERR]: 	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
[19Mar2023 14:35:35] [main/INFO]: [STDERR]: 	at space.vectrix.ignite.applaunch.handler.IgniteLaunchService.launchService0(IgniteLaunchService.java:214)
[19Mar2023 14:35:35] [main/INFO]: [STDERR]: 	at space.vectrix.ignite.applaunch.handler.IgniteLaunchService.lambda$launchService$1(IgniteLaunchService.java:112)
[19Mar2023 14:35:35] [main/INFO]: [STDERR]: 	at cpw.mods.modlauncher.LaunchServiceHandlerDecorator.launch(LaunchServiceHandlerDecorator.java:37)
[19Mar2023 14:35:35] [main/INFO]: [STDERR]: 	at cpw.mods.modlauncher.LaunchServiceHandler.launch(LaunchServiceHandler.java:54)
[19Mar2023 14:35:35] [main/INFO]: [STDERR]: 	at cpw.mods.modlauncher.LaunchServiceHandler.launch(LaunchServiceHandler.java:72)
[19Mar2023 14:35:35] [main/INFO]: [STDERR]: 	at cpw.mods.modlauncher.Launcher.run(Launcher.java:82)
[19Mar2023 14:35:35] [main/INFO]: [STDERR]: 	at cpw.mods.modlauncher.Launcher.main(Launcher.java:66)
[19Mar2023 14:35:35] [main/INFO]: [STDERR]: 	at space.vectrix.ignite.applaunch.IgniteBootstrap.run(IgniteBootstrap.java:192)
[19Mar2023 14:35:35] [main/INFO]: [STDERR]: 	at space.vectrix.ignite.applaunch.IgniteBootstrap.main(IgniteBootstrap.java:99)

PaperClip BootService

I try use
-Dignite.launch.service=paperclip -Dignite.paperclip.jar=./paper-1.17-49.jar
It will show
Exception in thread "main" java.lang.IllegalStateException: Unable to locate launch jar at '.\cache\patched_1.16.5.jar'.
at space.vectrix.ignite.applaunch.IgniteBootstrap.run(IgniteBootstrap.java:129)
at space.vectrix.ignite.applaunch.IgniteBootstrap.main(IgniteBootstrap.java:86)

it should be "patched_1.17.jar"

Mod Lifecycle

Mods should have a lifecycle in order to appropriately interact, apply mixin plugins, locate resources, and more.

This will require Implant to have an API, which can be injected into the main classes of the mods to be loaded. Plugins could be loaded using Guice, injecting in some of the API, or resource paths required. The main class could be registered as an event listener and have an initialization lifecycle. Mods could specify the classpath of the main class in the mod.json.

The lifecycle events could be listed as below.

CONSTRUCTION (mod resources are created),
INITIALIZATION (mixins and transformers are registered)

Mixin plugins could be registered on PRE_INITIALIZATION or INITIALIZATION as resources from configuration should be loaded by then.

There will also be a need to get mixin plugins to work in the first place. Will need to figure this one out.

ModifyVariable doesn't work

code

import com.llamalad7.mixinextras.sugar.Local;
import com.llamalad7.mixinextras.sugar.ref.LocalRef;
import net.minecraft.core.BlockPos;
import net.minecraft.core.MappedRegistry;
import net.minecraft.core.registries.Registries;
import net.minecraft.world.level.WorldGenLevel;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext;
import net.minecraft.world.level.levelgen.feature.TreeFeature;
import net.minecraft.world.level.levelgen.feature.configurations.TreeConfiguration;
import net.minecraft.world.level.levelgen.feature.foliageplacers.FoliagePlacer;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.ModifyVariable;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import top.missingbyriver.igniteleaves.mixin.plugins.CorePlugin;

import java.util.Set;

@Mixin(value = TreeFeature.class)
public abstract class MixinTreeFeature {
  @Inject(method = "place(Lnet/minecraft/world/level/levelgen/feature/FeaturePlaceContext;)Z", at = @At("HEAD"))
  protected void writeMapBeforePlace(FeaturePlaceContext<TreeConfiguration> context, CallbackInfoReturnable<Boolean> cir) {
    if (CorePlugin.featureMap.isEmpty()) {
      new Thread(() -> {
        var server = ((CraftServer) Bukkit.getServer()).getServer();
        var registry = (MappedRegistry<ConfiguredFeature<?, ?>>) server.worldLoader.datapackWorldgen().registryOrThrow(Registries.CONFIGURED_FEATURE);
        registry.entrySet().iterator().forEachRemaining(entry -> CorePlugin.featureMap.put(entry.getValue().feature(), entry.getKey().location().toString())
        );
        System.out.println("load FeatureMap");
      }).start();
    }
  }

  @ModifyVariable(
    method = "place(Lnet/minecraft/world/level/levelgen/feature/FeaturePlaceContext;)Z",
    at = @At("STORE"), ordinal = 0
  )
  private FoliagePlacer.FoliageSetter injected(FoliagePlacer.FoliageSetter value, @Local LocalRef<Set<BlockPos>> set3, @Local LocalRef<WorldGenLevel> worldGenLevel) {
    System.out.println("modified");
    return new FoliagePlacer.FoliageSetter() {
      @Override
      public void set(BlockPos pos, BlockState state) {
        System.out.println("abab");
        set3.get().add(pos.immutable());
        worldGenLevel.get().setBlock(pos, state, 19);
      }

      @Override
      public boolean isSet(BlockPos pos) {
        System.out.println("abab");
        return set3.get().contains(pos);
      }
    };
  }
}

log
latest.log

Java 17 deprecated SecurityManager

Java 17 warning

Caused by JEP 411

WARNING: A terminally deprecated method in java.lang.System has been called
WARNING: System::setSecurityManager has been called by space.vectrix.ignite.applaunch.service.PaperclipBootstrapService (file:/D:/Server/ignitetest/srv_ignite.jar)
WARNING: Please consider reporting this to the maintainers of space.vectrix.ignite.applaunch.service.PaperclipBootstrapService
WARNING: System::setSecurityManager will be removed in a future release

Server loads normally, but this warning says 'consider reporting this to the maintainers'

Info

Java: 17 (Temurin 17 build 35 64-bit)
OS: Windows 11 Pro x64
Server: Paper 1.17.1 (Using 'Paperclip' launch mode)
Mods: none
Plugins: none

Extra java arguments

Hi, is it possible to pass extra arguments to the server? Such as —nogui, -Xmx2G, and other performance arguments?

Paper 1.18.2

java -Xms11264M -Xmx11264M -XX:MaxRAMPercentage=95.0 -Dterminal.jline=false -Dterminal.ansi=true -Dignite.service=paper -jar ignite-launcher.jar -Dignite.paper.target=io.papermc.paperclip.Paperclip

[23:48:13 INFO] [Ignite Platform]: Loading [[email protected]].
Exception in thread "main" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
        at cpw.mods.modlauncher.LaunchServiceHandlerDecorator.launch(LaunchServiceHandlerDecorator.java:39)
        at cpw.mods.modlauncher.LaunchServiceHandler.launch(LaunchServiceHandler.java:54)
        at cpw.mods.modlauncher.LaunchServiceHandler.launch(LaunchServiceHandler.java:72)
        at cpw.mods.modlauncher.Launcher.run(Launcher.java:82)
        at cpw.mods.modlauncher.Launcher.main(Launcher.java:66)
        at space.vectrix.ignite.applaunch.IgniteBootstrap.run(IgniteBootstrap.java:192)
        at space.vectrix.ignite.applaunch.IgniteBootstrap.main(IgniteBootstrap.java:99)
Caused by: java.lang.reflect.InvocationTargetException
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:568)
        at space.vectrix.ignite.applaunch.handler.IgniteLaunchService.launchService0(IgniteLaunchService.java:214)
        at space.vectrix.ignite.applaunch.handler.IgniteLaunchService.lambda$launchService$1(IgniteLaunchService.java:112)
        at cpw.mods.modlauncher.LaunchServiceHandlerDecorator.launch(LaunchServiceHandlerDecorator.java:37)
        ... 6 more
Caused by: java.lang.RuntimeException: java.lang.ClassNotFoundException: org.bukkit.craftbukkit.Main
        at space.vectrix.ignite.launch.IgniteLaunch.launch(IgniteLaunch.java:72)
        at space.vectrix.ignite.launch.IgniteLaunch.main(IgniteLaunch.java:46)
        ... 13 more
Caused by: java.lang.ClassNotFoundException: org.bukkit.craftbukkit.Main
        at java.base/java.lang.ClassLoader.findClass(ClassLoader.java:718)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:587)
        at cpw.mods.modlauncher.TransformingClassLoader.loadClass(TransformingClassLoader.java:106)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
        at java.base/java.lang.Class.forName0(Native Method)
        at java.base/java.lang.Class.forName(Class.java:467)
        at space.vectrix.ignite.launch.IgniteLaunch.launch(IgniteLaunch.java:67)
        ... 14 more
        Suppressed: java.lang.ClassNotFoundException
                at cpw.mods.modlauncher.TransformingClassLoader$DelegatedClassLoader.findClass(TransformingClassLoader.java:282)
                at cpw.mods.modlauncher.TransformingClassLoader.loadClass(TransformingClassLoader.java:136)
                at cpw.mods.modlauncher.TransformingClassLoader.loadClass(TransformingClassLoader.java:98)
                ... 18 more

Relocate bundled libraries for better compatibility

Hello,

since all libraries bundled in this jar will be loaded by the system class loader, reflective access inside plugin shaded versions of the same libraries may break. It is common practice to change the namespace during packaging to ensure class definitions across multiple class loaders are consistent.

Currently I'm experiencing issues when using Guice in another plugin.

Since I'm not that familiar with gradle, I cannot supply a solution on how to do this properly with gradle.

It is cannot running

[15:13:56 INFO] [cpw.mods.modlauncher.LaunchServiceHandler]: Launching target 'ignitelaunch' with arguments [-Dignite.launch.service=paperclip]
Exception in thread "main" java.lang.NoSuchMethodError: 'void sun.security.util.ManifestEntryVerifier.(java.util.jar.Manifest)'
at cpw.mods.modlauncher.SecureJarHandler.createCodeSource(SecureJarHandler.java:66)
at cpw.mods.modlauncher.TransformingClassLoader$DelegatedClassLoader.findClass(TransformingClassLoader.java:275)
at cpw.mods.modlauncher.TransformingClassLoader.loadClass(TransformingClassLoader.java:136)
at cpw.mods.modlauncher.TransformingClassLoader.loadClass(TransformingClassLoader.java:98)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
at java.base/java.lang.Class.forName0(Native Method)
at java.base/java.lang.Class.forName(Class.java:467)
at space.vectrix.ignite.applaunch.handler.IgniteLaunchService.launchService0(IgniteLaunchService.java:212)
at space.vectrix.ignite.applaunch.handler.IgniteLaunchService.lambda$launchService$1(IgniteLaunchService.java:112)
at cpw.mods.modlauncher.LaunchServiceHandlerDecorator.launch(LaunchServiceHandlerDecorator.java:37)
at cpw.mods.modlauncher.LaunchServiceHandler.launch(LaunchServiceHandler.java:54)
at cpw.mods.modlauncher.LaunchServiceHandler.launch(LaunchServiceHandler.java:72)
at cpw.mods.modlauncher.Launcher.run(Launcher.java:82)
at cpw.mods.modlauncher.Launcher.main(Launcher.java:66)
at space.vectrix.ignite.applaunch.IgniteBootstrap.run(IgniteBootstrap.java:189)
at space.vectrix.ignite.applaunch.IgniteBootstrap.main(IgniteBootstrap.java:99)

I would like to execute this using Java 8.

[cpw.mods.modlauncher.LaunchServiceHandler]: Launching target 'ignitelaunch' with arguments [ignite.paper.override=false, paper.jar]
Exception in thread "main" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at cpw.mods.modlauncher.LaunchServiceHandlerDecorator.launch(LaunchServiceHandlerDecorator.java:39)
at cpw.mods.modlauncher.LaunchServiceHandler.launch(LaunchServiceHandler.java:54)
at cpw.mods.modlauncher.LaunchServiceHandler.launch(LaunchServiceHandler.java:72)
at cpw.mods.modlauncher.Launcher.run(Launcher.java:82)
at cpw.mods.modlauncher.Launcher.main(Launcher.java:66)
at space.vectrix.ignite.applaunch.IgniteBootstrap.run(IgniteBootstrap.java:192)
at space.vectrix.ignite.applaunch.IgniteBootstrap.main(IgniteBootstrap.java:99)
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at space.vectrix.ignite.applaunch.handler.IgniteLaunchService.launchService0(IgniteLaunchService.java:214)
at space.vectrix.ignite.applaunch.handler.IgniteLaunchService.lambda$launchService$1(IgniteLaunchService.java:112)
at cpw.mods.modlauncher.LaunchServiceHandlerDecorator.launch(LaunchServiceHandlerDecorator.java:37)
... 6 more
Caused by: java.lang.NullPointerException
at sun.reflect.annotation.TypeAnnotationParser.mapTypeAnnotations(TypeAnnotationParser.java:356)
at sun.reflect.annotation.AnnotatedTypeFactory$AnnotatedTypeBaseImpl.(AnnotatedTypeFactory.java:139)
at sun.reflect.annotation.AnnotatedTypeFactory.buildAnnotatedType(AnnotatedTypeFactory.java:65)
at sun.reflect.annotation.TypeAnnotationParser.buildAnnotatedTypes(TypeAnnotationParser.java:137)
at java.lang.reflect.Executable.getAnnotatedParameterTypes(Executable.java:695)
at com.google.inject.spi.InjectionPoint.(InjectionPoint.java:101)
at com.google.inject.spi.InjectionPoint.forConstructorOf(InjectionPoint.java:326)
at com.google.inject.internal.ConstructorBindingImpl.create(ConstructorBindingImpl.java:121)
at com.google.inject.internal.InjectorImpl.createUninitializedBinding(InjectorImpl.java:715)
at com.google.inject.internal.InjectorImpl.createJustInTimeBinding(InjectorImpl.java:941)
at com.google.inject.internal.InjectorImpl.createJustInTimeBindingRecursive(InjectorImpl.java:863)
at com.google.inject.internal.InjectorImpl.getJustInTimeBinding(InjectorImpl.java:300)
at com.google.inject.internal.InjectorImpl.getBindingOrThrow(InjectorImpl.java:223)
at com.google.inject.internal.InjectorImpl.getInternalFactory(InjectorImpl.java:949)
at com.google.inject.internal.FactoryProxy.notify(FactoryProxy.java:48)
at com.google.inject.internal.ProcessedBindingData.runCreationListeners(ProcessedBindingData.java:60)
at com.google.inject.internal.InternalInjectorCreator.initializeStatically(InternalInjectorCreator.java:137)
at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:110)
at com.google.inject.Guice.createInjector(Guice.java:87)
at com.google.inject.Guice.createInjector(Guice.java:69)
at com.google.inject.Guice.createInjector(Guice.java:59)
at space.vectrix.ignite.launch.IgniteLaunch.(IgniteLaunch.java:53)
at space.vectrix.ignite.launch.IgniteLaunch.main(IgniteLaunch.java:46)
... 13 more

Compatibility question

does this support for paper 1.8.8
if i try use ignite for paper 1.8.8 it will show
java.lang.NoSuchMethodError: com.google.common.collect.MapMaker.softValues()Lcom/google/common/collect/MapMaker;
at org.bukkit.craftbukkit.v1_8_R3.CraftServer.(CraftServer.java:146) ~[CraftServer.class:git-PaperSpigot-"4c7641d"]
at net.minecraft.server.v1_8_R3.PlayerList.(PlayerList.java:71) ~[PlayerList.class:git-PaperSpigot-"4c7641d"]
at net.minecraft.server.v1_8_R3.DedicatedPlayerList.(SourceFile:14) ~[DedicatedPlayerList.class:git-PaperSpigot-"4c7641d"]
at net.minecraft.server.v1_8_R3.DedicatedServer.init(DedicatedServer.java:176) ~[DedicatedServer.class:git-PaperSpigot-"4c7641d"]
at net.minecraft.server.v1_8_R3.MinecraftServer.run(MinecraftServer.java:563) [MinecraftServer.class:git-PaperSpigot-"4c7641d"]
at java.lang.Thread.run(Thread.java:834) [?:?]
[02:16:56 ERROR]: This crash report has been saved to: /home/map/./crash-reports/crash-2021-10-05_02.16.56-server.txt

Mod Dependencies

Mods should be able to specify dependencies on other mods, in order for some mods to wait until others are loaded on the classpath. There should be the ability to specify a list of mods in the mod.json as softDependencies which are optional dependencies to be loaded first if found. Otherwise, normal dependencies are required to be loaded first.

The dependencies could be specified like such...

name@version

With the @version being an optional value to add if you wish to target a specific release of a mod.

Unable to boot paper 1.20.2

[24Nov2023 12:06:49] [main/INFO]: Ignite Launcher v0.8.1
[24Nov2023 12:06:49] [main/INFO]: Preparing ModLauncher with arguments [nogui, --launchTarget, ignitelaunch]
[24Nov2023 12:06:49] [main/INFO]: ModLauncher running: args [nogui, --launchTarget, ignitelaunch]
[24Nov2023 12:06:49] [main/INFO]: ModLauncher 8.1.3+8.1.3+main-8.1.x.c94d18ec starting: java version 17.0.6 by Amazon.com Inc.
[24Nov2023 12:06:49] [main/INFO]: SpongePowered MIXIN Subsystem Version=0.8.5 Source=file:/E:/Servers/1.20.2%20test%20server/ignite-launcher.jar Service=ModLauncher Env=SERVER
[24Nov2023 12:06:49] [main/INFO]: Cannot locate mod directory '.\mods'. Creating a new one...
[24Nov2023 12:06:49] [main/INFO]: Cannot locate config directory '.\configs'. Creating a new one...
[24Nov2023 12:06:49] [main/INFO]: Located 1 mod(s).
[24Nov2023 12:06:49] [main/INFO]: Applied transformer(s).
[24Nov2023 12:06:49] [main/INFO]: Launching target 'ignitelaunch' with arguments [nogui]
[24Nov2023 12:06:50] [main/INFO]: Loading [[email protected]].
[24Nov2023 12:06:50] [main/WARN]: Configuration conflict: there is more than one oshi.properties file on the classpath: [jar:file:/E:/Servers/1.20.2%20test%20server/libraries/com/github/oshi/oshi-core/6.4.5/oshi-core-6.4.5.jar!/oshi.properties, jar:file:/E:/Servers/1.20.2%20test%20server/libraries/com/github/oshi/oshi-core/6.4.5/oshi-core-6.4.5.jar!/oshi.properties]
[24Nov2023 12:06:51] [main/WARN]: Configuration conflict: there is more than one oshi.architecture.properties file on the classpath: [jar:file:/E:/Servers/1.20.2%20test%20server/libraries/com/github/oshi/oshi-core/6.4.5/oshi-core-6.4.5.jar!/oshi.architecture.properties, jar:file:/E:/Servers/1.20.2%20test%20server/libraries/com/github/oshi/oshi-core/6.4.5/oshi-core-6.4.5.jar!/oshi.architecture.properties]
[24Nov2023 12:06:55] [main/INFO]: Environment: Environment[accountsHost=https://api.mojang.com, sessionHost=https://sessionserver.mojang.com, servicesHost=https://api.minecraftservices.com, name=PROD]
[24Nov2023 12:06:56] [main/INFO]: Found new data pack file/bukkit, loading it automatically
[24Nov2023 12:06:57] [main/INFO]: Loaded 7 recipes
[24Nov2023 12:06:57] [Server thread/INFO]: Starting minecraft server version 1.20.2
[24Nov2023 12:06:57] [Server thread/INFO]: Loading properties
[24Nov2023 12:06:57] [Server thread/INFO]: This server is running Paper version git-Paper-299 (MC: 1.20.2) (Implementing API version 1.20.2-R0.1-SNAPSHOT) (Git: 96d5e6c)
[24Nov2023 12:06:58] [Server thread/INFO]: Server Ping Player Sample Count: 12
[24Nov2023 12:06:58] [Server thread/INFO]: Using 4 threads for Netty based IO
[24Nov2023 12:06:58] [Server thread/ERROR]: Encountered an unexpected exception
java.lang.NoSuchFieldError: DEFAULT_OPTIONS_SOURCE
	at org.spongepowered.configurate.yaml.YamlConfigurationLoader$Builder.<init>(YamlConfigurationLoader.java:86) ~[configurate-yaml-4.2.0-SNAPSHOT.jar:?]
	at org.spongepowered.configurate.yaml.YamlConfigurationLoader.builder(YamlConfigurationLoader.java:65) ~[configurate-yaml-4.2.0-SNAPSHOT.jar:?]
	at io.papermc.paper.configuration.ConfigurationLoaders.naturallySorted(ConfigurationLoaders.java:14) ~[?:git-Paper-299]
	at io.papermc.paper.configuration.Configurations.createLoaderBuilder(Configurations.java:68) ~[?:git-Paper-299]
	at io.papermc.paper.configuration.PaperConfigurations.createLoaderBuilder(PaperConfigurations.java:160) ~[?:git-Paper-299]
	at io.papermc.paper.configuration.Configurations.createGlobalLoaderBuilder(Configurations.java:83) ~[?:git-Paper-299]
	at io.papermc.paper.configuration.PaperConfigurations.createGlobalLoaderBuilder(PaperConfigurations.java:183) ~[?:git-Paper-299]
	at io.papermc.paper.configuration.Configurations.initializeGlobalConfiguration(Configurations.java:121) ~[?:git-Paper-299]
	at io.papermc.paper.configuration.Configurations.initializeGlobalConfiguration(Configurations.java:106) ~[?:git-Paper-299]
	at io.papermc.paper.configuration.PaperConfigurations.initializeGlobalConfiguration(PaperConfigurations.java:198) ~[?:git-Paper-299]
	at net.minecraft.server.dedicated.DedicatedServer.e(DedicatedServer.java:209) ~[?:git-Paper-299]
	at net.minecraft.server.MinecraftServer.w(MinecraftServer.java:1086) ~[?:git-Paper-299]
	at net.minecraft.server.MinecraftServer.lambda$spin$0(MinecraftServer.java:315) ~[?:git-Paper-299]
	at java.lang.Thread.run(Thread.java:833) ~[?:?]
[24Nov2023 12:06:58] [Server thread/WARN]: Configuration conflict: there is more than one oshi.architecture.properties file on the classpath: [jar:file:/E:/Servers/1.20.2%20test%20server/libraries/com/github/oshi/oshi-core/6.4.5/oshi-core-6.4.5.jar!/oshi.architecture.properties, jar:file:/E:/Servers/1.20.2%20test%20server/libraries/com/github/oshi/oshi-core/6.4.5/oshi-core-6.4.5.jar!/oshi.architecture.properties]
[24Nov2023 12:06:58] [Server thread/ERROR]: This crash report has been saved to: E:\Servers\1.20.2 test server\.\crash-reports\crash-2023-11-24_12.06.58-server.txt
[24Nov2023 12:06:58] [Server thread/INFO]: Stopping server
[24Nov2023 12:06:58] [Server thread/INFO]: Saving players
[24Nov2023 12:06:58] [Server thread/INFO]: Saving worlds
[24Nov2023 12:06:58] [Server thread/INFO]: ThreadedAnvilChunkStorage: All dimensions are saved
[24Nov2023 12:06:58] [Server thread/INFO]: Flushing Chunk IO
[24Nov2023 12:06:58] [Server thread/ERROR]: Exception stopping the server
java.lang.NullPointerException: Cannot read the array length because "io.papermc.paper.chunk.system.io.RegionFileIOThread.threads" is null
	at io.papermc.paper.chunk.system.io.RegionFileIOThread.close(RegionFileIOThread.java:189) ~[?:git-Paper-299]
	at net.minecraft.server.MinecraftServer.t(MinecraftServer.java:977) ~[?:git-Paper-299]
	at net.minecraft.server.dedicated.DedicatedServer.t(DedicatedServer.java:820) ~[?:git-Paper-299]
	at net.minecraft.server.MinecraftServer.w(MinecraftServer.java:1195) ~[?:git-Paper-299]
	at net.minecraft.server.MinecraftServer.lambda$spin$0(MinecraftServer.java:315) ~[?:git-Paper-299]
	at java.lang.Thread.run(Thread.java:833) ~[?:?]

This is after a fresh install

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.