Compare commits

..

9 commits

42 changed files with 26805 additions and 395 deletions

View file

@ -38,13 +38,6 @@ export default defineConfig({
{ text: 'AccessWideners', link: '/tutorial/accesswideners' },
]
},
{
text: 'Contributing',
items: [
{ text: 'Guidelines', link: '/contributing/guidelines' },
{ text: 'Tools', link: '/contributing/tools' },
]
},
{
text: 'Specifications',
items: [
@ -52,7 +45,23 @@ export default defineConfig({
{ text: '*.mixins.json', link: '/spec/mixin-config' },
{ text: '*.accesswidener', link: '/spec/aw' },
]
}
},
{
text: 'Extensions',
items: [
{ text: 'Entrypoints', link: '/exts/entrypoints' },
{ text: 'Mixin', link: '/exts/mixin' },
{ text: 'AccessWideners', link: '/exts/aw' },
{ text: 'PreLaunch', link: '/exts/prelaunch' },
]
},
{
text: 'Contributing',
items: [
{ text: 'Guidelines', link: '/contributing/guidelines' },
{ text: 'Tools', link: '/contributing/tools' },
]
},
],
socialLinks: [
@ -69,7 +78,7 @@ export default defineConfig({
copyright: 'Copyright © 2024 FrogMC, <a href="https://git.frogmc.dev/frogmc/frogmc.dev">licensed under Apache-2.0</a>'
},
editLink: {
pattern: 'https://git.frogmc.dev/frogmc/frogmc.dev/_edit/mistress/:path'
pattern: 'https://git.frogmc.dev/frogmc/frogmc.dev/edit/mistress/:path'
},
outline: 'deep',
externalLinkIcon: true

View file

@ -141,17 +141,13 @@
* Custom styling
* -------------------------------------------------------------------------- */
button {
color: var(--vp-button-brand-text);
padding: 4px;
}
.main button {
border-radius: 14px;
background-color: var(--vp-button-brand-bg);
color: var(--vp-button-brand-text);
border-color: var(--vp-button-brand-border);
padding: 4px;
border-radius: 14px;
}
button:disabled {
background-color: var(--vp-c-default-soft);
}
button:hover:not(:disabled) {
button:hover {
background-color: var(--vp-button-brand-hover-bg);
color: var(--vp-button-brand-hover-text);
border-color: var(--vp-button-brand-hover-border);
@ -165,12 +161,8 @@ select, input {
border-radius: 12px;
}
select {
background-color: var(--vp-c-brand-soft);
text-align: center;
}
select:hover {
cursor: pointer;
}
input {
border: 4px solid var(--vp-c-brand-soft);
}

1
FrogLoader Submodule

@ -0,0 +1 @@
Subproject commit cf4996e1ffe6e03474bd150dc4d0545e9aad9bde

View file

@ -52,14 +52,6 @@ const members = [
title: 'Moderator',
links: [
]
},
{
avatar: 'https://git.frogmc.dev/ender.png',
name: 'Ender',
title: 'Developer',
links: [
]
}
]
@ -77,4 +69,4 @@ const members = [
<VPTeamMembers
:members="members"
/>
</VPTeamPage>
</VPTeamPage>

49
api-examples.md Normal file
View file

@ -0,0 +1,49 @@
---
outline: deep
---
# Runtime API Examples
This page demonstrates usage of some of the runtime APIs provided by VitePress.
The main `useData()` API can be used to access site, theme, and page data for the current page. It works in both `.md` and `.vue` files:
```md
<script setup>
import { useData } from 'vitepress'
const { theme, page, frontmatter } = useData()
</script>
## Results
### Theme Data
<pre>{{ theme }}</pre>
### Page Data
<pre>{{ page }}</pre>
### Page Frontmatter
<pre>{{ frontmatter }}</pre>
```
<script setup>
import { useData } from 'vitepress'
const { site, theme, page, frontmatter } = useData()
</script>
## Results
### Theme Data
<pre>{{ theme }}</pre>
### Page Data
<pre>{{ page }}</pre>
### Page Frontmatter
<pre>{{ frontmatter }}</pre>
## More
Check out the documentation for the [full list of runtime APIs](https://vitepress.dev/reference/runtime-api#usedata).

2
exts/aw.md Normal file
View file

@ -0,0 +1,2 @@
# AccessWidener
[AccessWidener](https://github.com/FabricMC/access-widener) is a format for modifying class access restrictions created by the Fabric project. AccessWideners allow private or protected classes, fields, and methods to be made public, and for final fields to be made mutable.

90
exts/entrypoints.md Normal file
View file

@ -0,0 +1,90 @@
# Entrypoints
Entrypoints are a specific type of extension that allows mods to inject code that will run as the game is starting up. They can be thought of as like the `main()` function in a full Program, and are primarily used for adding things to registries, declaring callbacks and events, and other tasks your mod needs to do once during startup.
## `MainExtension`
The `MainExtension` entrypoint contains the core of your mod's initialization code. `MainExtension` will run during the startup sequence on both the server and the client, and thus should be populated with things like registrations (i.e. of blocks, items, entities) and events that are triggered on both the server and client side.
The first step to creating a MainExtension entrypoint is to create a class. This should usually be in the root package of your mod, but does not have to be. For this example, we will create a class called `ExampleInit` that implements the interface `MainExtension`:
```java
package com.example.examplemod;
public class ExampleInit implements MainExtension {
...
}
```
Once this class is created, add it under the `[frog.extensions]` table in your `frog.mod.toml` file with the key `init`:
```toml
[frog.extensions]
...
init = "com/example/examplemod/ExampleInit"
...
```
The interface `MainExtension` contains one method, called `onInit`. It takes one `ModProperties` object and returns `void`. We will implement this method by adding a Logger and printing a message:
```java
package com.example.examplemod;
import dev.frogmc.frogloader.api.mod.ModProperties;
import dev.frogmc.froglib.entrypoints.MainExtension;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public final Logger LOGGER = LoggerFactory.getLogger("ExampleMod");
public class ExampleInit implements MainExtension {
@Override
public void onInit(ModProperties mod) {
LOGGER.info("ribbit world");
}
}
```
Now, when we launch the game with the example mod installed, we will see that message sent when our mod is initialized.
## `ClientExtension`
The `ClientExtension` is very similar to the `MainExtension` in its function as an entrypoint, except it will only run if the mod is installed on the client. This is primarily used for modifying the behavior of rendering, like through custom models or renderers, as well as keybinds and other interactions that are only processed on the client side. To create a ClientExtension entrypoint, the process is very similar; first, we will create a class implementing the interface `ClientExtension`. This class should be annotated with the `@ClientOnly` annotation so that it is only loaded into the classpath on the client. Usually it should be placed in a package specifically for client-related classes.
```java
package com.example.examplemod.client;
import dev.frogmc.frogloader.api.mod.ModProperties;
import dev.frogmc.frogloader.api.env.ClientOnly;
import dev.frogmc.froglib.entrypoints.ClientExtension;
@ClientOnly
public class ExampleClientInit implements ClientExtension {
@Override
public void onClientInit(ModProperties mod) {
...
}
}
```
This should also be included in the `[frog.extensions]` table in your `frog.mod.toml`, under the key `client`:
```toml
[frog.extensions]
...
client = "com/example/examplemod/client/ExampleClientInit"
...
```
## `ServerExtension`
`ServerExtension` is very similar to `ClientExtension` in implementation, except it runs only on the dedicated server. It does **not** run on the internal server. To create a ServerExtension entrypoint, create a class implementing `ServerExtension` annotated with `@ServerOnly`.
```java
package com.example.examplemod.server;
import dev.frogmc.frogloader.api.mod.ModProperties;
import dev.frogmc.frogloader.api.env.ServerOnly;
import dev.frogmc.froglib.entrypoints.ServerExtension;
@ServerOnly
public class ExampleServerInit implements ServerExtension {
@Override
public void onServerInit(ModProperties mod) {
...
}
}
```
Add this to the `[frog.extensions]` table in your `frog.mod.toml` file, under the key `server`:
```toml
[frog.extensions]
...
server = "com/example/examplemod/server/ExampleServerInit"
...
```

96
exts/mixin.md Normal file
View file

@ -0,0 +1,96 @@
# Mixin
[Mixin](https://github.com/SpongePowered/Mixin) is an ASM framework to modify the code of the game created by the SpongePowered project. Mixin is widely supported by many modloaders, and frog is no exception, offering support for using Mixin in mods. This document is not intended as a comprehensive tutorial on the specifics of Mixin, but it is designed to give a basic understanding of its principles as well as how to use it in a frog mod.
## Adding Mixins
A Mixin is a specially-annotated class that goes in a package within your mod. Mixins, by default, are common to both the server and client; however, it is possible to write a server or client-specific mixin. By convention, this package is called `mixin` and is in the root package of your mod. Additionally, a metadata file called `<modid>.mixins.json` (with `<modid>` replaced with your mod's namespace id) should be located in your `resources` folder. It should be in JSON format, and should have the following fields:
- `required`: internal use; should be set to `true`.
- `minVersion`: the minimum supported version of Mixin. Should be set to `"0.8".
- `package`: the package that contains your mixins.
- `compatibilityLevel`: the version of java your mixins should be compatible with. Should be formatted as `JAVA_` followed by the major version, i.e. `JAVA_17`, `JAVA_21`
- `mixins`: an array of strings containing the names of mixins that will apply on both the client and server. Should be just the names of mixin classes.
- `client`: an array of strings containing the names of mixins that will apply on just the client. Should be just the names of mixin classes.
- `server`: an array of strings containing the names of mixins that will apply on just the server. Should be just the names of mixin classes.
- `injectors`: internal use; should be set to `{ "defaultRequire": 1 }`
The following is an example of a .mixins.json file containing no mixins:
```json
{
"required": true,
"minVersion": "0.8",
"package": "com.example.examplemod.mixin",
"compatibilityLevel": "JAVA_21",
"mixins": [],
"client": [],
"server": [],
"injectors": {
"defaultRequire": 1
}
}
```
For the mixins to apply, this file must be included in the `[frog.extensions]` table in your `frog.mod.toml` file, as follows:
```toml
[frog.extensions]
...
mixin = "<modid>.mixins.json"
...
```
Replace `<modid>` with your mod's namespace id, and you're ready to write mixins!
## Mixin Example
A Mixin represents a hook to modify a single class of Minecraft code. The mixin takes the form of a class with an annotation. For this example, we will create a Mixin class that will modify the title screen. Begin by creating a Mixin class in the `mixin` package. Although other naming schemes are used, typically it's not a bad idea to name your file the name of the package you're modifying followed by the word `Mixin`. So, to modify the `TitleScreen` class, we'll create a class called `TitleScreenMixin`. Create this file, and add the `@Mixin` annotation to specify what class we'll be modifying.
```java
package com.example.examplemod.mixin;
import net.minecraft.client.gui.screens.TitleScreen;
import org.spongepowered.asm.mixin.Mixin;
@Mixin(TitleScreen.class)
public class TitleScreenMixin {
}
```
We have to add this to our previously-created `<modid>.mixins.json` file for the loader to recognize it. Since we will be modifying the title screen, we will put the class name of our mixin in the `client` array instead of the `mixins` array:
```json
client: ["TitleScreenMixin"]
```
With this added to our Mixin configuration it should now attempt to load, however there are still errors in our mixin. This is because the signature of the mixin class must match that of the class that is being modified. `TitleScreen` extends the `Screen` class, so our mixin must also extend `Screen`. To not have to implement all of the classes within `Screen`, we can mark the class abstract.
```java
package com.example.examplemod.mixin;
import net.minecraft.client.gui.screens.TitleScreen;
import net.minecraft.client.gui.screens.Screen;
import org.spongepowered.asm.mixin.Mixin;
@Mixin(TitleScreen.class)
public abstract class TitleScreenMixin extends Screen {
protected TitleScreenMixin(Component title) {
super(title);
}
}
```
Now, we have a mixin that will do nothing, however it is set up to modify the `TitleScreen` class. For this tutorial we will use one of the simplest Mixin types: the **Injector**. An injector adds code into an existing method within the target function, as if the code were copied and pasted from your mixin class to the game's code. In this case, we will inject into the method that adds menu elements to the title screen, called `createNormalMenuOptions`. We want this element to be added last, or at the tail of the method. With this in mind, we can write our mixin function header, within the mixin class:
```java
...
@Inject(method = "createNormalMenuOptions", at = @At("TAIL"))
private void showExample(int y, int rowHeight, CallbackInfo ci) {
...
}
```
Note that the arguments of the method are the same as the arguments of the method we're going to inject into, with the addition of a parameter of type `CallbackInfo`. The `CallbackInfo` parameter provides information about the method to the mixin. Keep in mind that returning in the mixin will not return the target method, but will just return to the existing code of that method. For this example, we'll add a text widget to the title screen, just to show us that the game has been modified.
```java
...
private void showExample(int y, int rowHeight, CallbackInfo ci) {
var widget = new FocusableTextWidget(200, Component.literal("<insert frog here!>"), this.font);
widget.setPosition(width / 2 - widget.getWidth(), 20);
addRenderableOnly(widget);
}
```
Now launch the game, and if everything worked properly you should see the text "<insert frog here!>" on the title screen!
For more advanced information about the Mixin system, see [the Mixin wiki](https://github.com/SpongePowered/Mixin/wiki).

1
exts/prelaunch.md Normal file
View file

@ -0,0 +1 @@
# PreLaunch

View file

@ -1,8 +1,3 @@
---
- head:
---
# Client
Here's how to install FrogLoader to your game.
@ -26,89 +21,42 @@ Insert section about the installer here
const showSnapshots = ref()
const versionSelector = ref()
let releases = []
let snapshots = []
let versions = []
let loaderLibs
async function getGameVersions() {
const response = await fetch("https://piston-meta.mojang.com/mc/game/version_manifest_v2.json")
return await response.json()
}
async function getVersions() {
let optionString = ""
function getVersions() {
versionSelector.value.innerHTML = ""
for (let version of releases) {
versionSelector.value.innerHTML += "<option value=\""+version.id+"\">"+version.id+"</option>"
}
if (showSnapshots.value) {
for (let version of versions) {
optionString += "<option value=\""+version.id+"\">"+version.id+"</option>"
}
} else {
for (let version of releases) {
optionString += "<option value=\""+version.id+"\">"+version.id+"</option>"
for (let version of snapshots) {
versionSelector.value.innerHTML += "<option value=\""+version.id+"\">"+version.id+"</option>"
}
}
versionSelector.value.innerHTML = optionString
}
async function fetchLibraries() {
let response = await fetch("https://meta.frogmc.dev/v1/loader/version/latest")
let json = await response.json()
loaderLibs = json
}
onMounted(() => {
Promise.all([
getGameVersions().then((v) => {
versions = v.versions
for (let version of versions){
if (version.type === "release"){
releases.push(version)
}
getGameVersions().then((v) => {
versions = v.versions
for (let version of versions){
if (version.type === "snapshot"){
snapshots.push(version)
} else {
releases.push(version)
}
getVersions()
}),
fetchLibraries()
]).then((unused) => {
let button = document.getElementById("download")
button.innerHTML = "Download"
button.disabled = false
}).catch((err) => {
let html = "<div class=\"danger custom-block\"><p class=\"custom-block-title\">Error loading versions</p><p>"
html += err
html += "</p></div>"
document.getElementById("missingBox").innerHTML = html
}
getVersions()
})
})
async function getLwjglVersion() {
const versionUrl = versions[versionSelector.value.selectedIndex].url
let versionResponse = await fetch(versionUrl)
let versionJson = await versionResponse.json()
for (let lib of versionJson.libraries) {
let matcher = lib.name.match(/org.lwjgl:lwjgl:(\d+\.\d+\.\d+.*)/)
if (matcher != undefined) {
return matcher[1]
}
}
}
function getPlatform(){
const appVersion = navigator.appVersion
if(appVersion.indexOf("Linux")!=-1 || appVersion.indexOf("X11")!=-1 || appVersion.indexOf("Wayland")!=-1){
return "linux"
} else if(appVersion.indexOf("Win")!=-1){
return "windows"
} else if(appVersion.indexOf("Mac")!=-1){
if(navigator.platform.indexOf("x86-64")!=-1){
return "macos-x64"
}
return "macos-arm64"
}
}
async function download(){
function download(){
let missing = []
if (instanceNameRef.value === undefined){
@ -125,54 +73,8 @@ Insert section about the installer here
let zip = JSZip()
let promises = []
let lwjglVersion = await getLwjglVersion()
let platform = getPlatform()
promises.push(
readAsset("/mmc-pack.json").then((data) => {
if (lwjglVersion.split(".")[0] == 3) {
data = data.replaceAll("$lwjgl_major", "3")
} else {
data = data.replaceAll("$lwjgl_major", "")
}
zip.file("mmc-pack.json", data
.replaceAll("$lwjgl_version", lwjglVersion))
})
)
promises.push(
readAsset("/instance.cfg").then((data) => {
if (platform === "linux") {
data = data.replaceAll("$override_env", "true")
data = data.replaceAll("$env", "Env=@Variant(\\0\\0\\0\\b\\0\\0\\0\\x1\\0\\0\\0\\x36\\0_\\0_\\0G\\0L\\0_\\0T\\0H\\0R\\0\\x45\\0\\x41\\0\\x44\\0\\x45\\0\\x44\\0_\\0O\\0P\\0T\\0I\\0M\\0I\\0Z\\0\\x41\\0T\\0I\\0O\\0N\\0S\\0\\0\\0\\n\\0\\0\\0\\x2\\0\\x30)")
} else {
data = data.replaceAll("$override_env", "false")
data = data.replaceAll("$env", "@Variant(\\0\\0\\0\\b\\0\\0\\0\\0)")
}
zip.file("instance.cfg", data)
})
)
promises.push(
readAsset("/patches/dev.frogmc.frogloader.json").then((data) => {
let json = JSON.parse(data)
let libs = json.libraries
for (let lib of loaderLibs.libraries) {
let value = {
"downloads": {
"artifact": {
"url": lib.url,
"size": lib.size,
"sha1": lib.sha1
}
},
"name": lib.name
}
libs.push(value)
}
zip.folder("patches").file("dev.frogmc.frogloader.json", JSON.stringify(json))
})
)
Promise.all(promises).then((values) => {
zip.generateAsync({type:"blob"}).then(function (blob) {
@ -186,9 +88,8 @@ Insert section about the installer here
async function readAsset(path){
const response = await fetch(assetBaseUrl+path)
return await response.text().then((data) => {
return data.replaceAll("$instance_name", instanceNameRef.value)
.replaceAll("$loader_version", loaderLibs.version)
.replaceAll("$game_version", versionSelector.value.value)
data = data.replaceAll("$instance_name", instanceNameRef.value)
return data
})
}
@ -197,6 +98,10 @@ Insert section about the installer here
}
</script>
::: warning Dependencies for a generator here
- loader libraries in meta
:::
Add an instance generator to the installer and describe it here\
**or**\
PR direct support to Prism
@ -217,8 +122,12 @@ PR direct support to Prism
<input type="checkbox" v-model="showSnapshots" @change="getVersions">Show Snapshots</input>
</td>
</tr>
<tr>
<td></td>
<td></td>
</tr>
</tbody>
</table>
<div id="missingBox"></div>
<button id="download" @click="download" disabled>Loading...</button>
<button @click="download">Download</button>
</div>

85
markdown-examples.md Normal file
View file

@ -0,0 +1,85 @@
# Markdown Extension Examples
This page demonstrates some of the built-in markdown extensions provided by VitePress.
## Syntax Highlighting
VitePress provides Syntax Highlighting powered by [Shiki](https://github.com/shikijs/shiki), with additional features like line-highlighting:
**Input**
````md
```js{4}
export default {
data () {
return {
msg: 'Highlighted!'
}
}
}
```
````
**Output**
```js{4}
export default {
data () {
return {
msg: 'Highlighted!'
}
}
}
```
## Custom Containers
**Input**
```md
::: info
This is an info box.
:::
::: tip
This is a tip.
:::
::: warning
This is a warning.
:::
::: danger
This is a dangerous warning.
:::
::: details
This is a details block.
:::
```
**Output**
::: info
This is an info box.
:::
::: tip
This is a tip.
:::
::: warning
This is a warning.
:::
::: danger
This is a dangerous warning.
:::
::: details
This is a details block.
:::
## More
Check out the documentation for the [full list of markdown extensions](https://vitepress.dev/guide/markdown).

1812
package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,74 +0,0 @@
[General]
AutoCloseConsole=false
CloseAfterLaunch=false
ConfigVersion=1.2
CustomGLFWPath=
CustomOpenALPath=
EnableFeralGamemode=false
EnableMangoHud=false
Env=$env
ExportAuthor=
ExportName=
ExportOptionalFiles=true
ExportSummary=
ExportVersion=1.0.0
IgnoreJavaCompatibility=false
InstanceAccountId=
InstanceType=OneSix
JavaArchitecture=
JavaPath=
JavaRealArchitecture=
JavaSignature=
JavaVendor=
JavaVersion=
JoinServerOnLaunch=false
JoinServerOnLaunchAddress=
JvmArgs=
LaunchMaximized=false
LogPrePostOutput=true
ManagedPack=false
ManagedPackID=
ManagedPackName=
ManagedPackType=
ManagedPackVersionID=
ManagedPackVersionName=
MaxMemAlloc=2048
MinMemAlloc=512
MinecraftWinHeight=480
MinecraftWinWidth=854
OnlineFixes=false
OverrideCommands=false
OverrideConsole=false
OverrideEnv=$override_env
OverrideGameTime=false
OverrideJava=false
OverrideJavaArgs=false
OverrideJavaLocation=false
OverrideLegacySettings=false
OverrideMemory=false
OverrideMiscellaneous=false
OverrideNativeWorkarounds=false
OverridePerformance=false
OverrideWindow=false
PermGen=128
PostExitCommand=
PreLaunchCommand=
Profiler=
QuitAfterGameStop=false
RecordGameTime=true
ShowConsole=false
ShowConsoleOnError=true
ShowGameTime=true
UseAccountForInstance=false
UseDiscreteGpu=true
UseNativeGLFW=false
UseNativeOpenAL=false
UseZink=false
WrapperCommand=
iconKey=default
lastLaunchTime=1717870111279
lastTimePlayed=5229
linkedInstances=[]
name=$instance_name
notes=
totalTimePlayed=0

View file

@ -1,30 +0,0 @@
{
"components": [
{
"cachedName": "LWJGL $lwjgl_major",
"cachedVolatile": true,
"dependencyOnly": true,
"uid": "org.lwjgl$lwjgl_major",
"version": "$lwjgl_version"
},
{
"cachedName": "Minecraft",
"cachedRequires": [
{
"suggests": "$lwjgl_version",
"uid": "org.lwjgl$lwjgl_major"
}
],
"important": true,
"uid": "net.minecraft",
"version": "$game_version"
},
{
"cachedName": "FrogLoader",
"important": true,
"uid": "dev.frogmc.frogloader",
"version": "$loader_version"
}
],
"formatVersion": 1
}

View file

@ -2,8 +2,81 @@
"formatVersion": 1,
"name": "FrogLoader",
"uid": "dev.frogmc.frogloader",
"version": "$loader_version",
"libraries": [ ],
"version": "0.0.1-SNAPSHOT",
"libraries": [
{
"downloads": {
"artifact": {
"size": 120676,
"sha1": "9bf1d861a97bdd799ba1ae614a5a1b4f4f86d1d1",
"url": "https://maven.frogmc.dev/snapshots/dev/frogmc/frogloader/0.0.1-SNAPSHOT/frogloader-0.0.1-20240608.093414-3.jar"
}
},
"name": "dev.frogmc:frogloader:0.0.1-SNAPSHOT"
},
{
"name": "dev.frogmc:thyroxine:1.0.0-SNAPSHOT",
"downloads": {
"artifact": {
"size": 36102,
"sha1": "9fd87f91ccaf70f818b1f564101feb75306f99a9",
"url": "https://maven.frogmc.dev/snapshots/dev/frogmc/thyroxine/1.0.0-SNAPSHOT/thyroxine-1.0.0-20240607.131732-1.jar"
}
}
},
{
"name": "net.fabricmc:sponge-mixin:0.14.0+mixin.0.8.6",
"url": "https://maven.fabricmc.net"
},
{
"name": "io.github.llamalad7:mixinextras-common:0.3.6",
"url": "https://repo.maven.apache.org/maven2"
},
{
"name": "com.electronwill.night-config:toml:3.7.2",
"url": "https://repo.maven.apache.org/maven2"
},
{
"name": "com.electronwill.night-config:core:3.7.2",
"url": "https://repo.maven.apache.org/maven2"
},
{
"name": "org.ow2.asm:asm:9.7",
"url": "https://repo.maven.apache.org/maven2"
},
{
"name": "org.ow2.asm:asm-commons:9.7",
"url": "https://repo.maven.apache.org/maven2"
},
{
"name": "org.ow2.asm:asm-tree:9.7",
"url": "https://repo.maven.apache.org/maven2"
},
{
"name": "org.ow2.asm:asm-util:9.7",
"url": "https://repo.maven.apache.org/maven2"
},
{
"name": "org.ow2.asm:asm-analysis:9.7",
"url": "https://repo.maven.apache.org/maven2"
},
{
"name": "org.slf4j:slf4j-api:2.0.13",
"url": "https://repo.maven.apache.org/maven2"
},
{
"name": "org.apache.logging.log4j:log4j-slf4j2-impl:2.23.1",
"url": "https://repo.maven.apache.org/maven2"
},
{
"name": "org.apache.logging.log4j:log4j-api:2.23.1",
"url": "https://repo.maven.apache.org/maven2"
},
{
"name": "org.apache.logging.log4j:log4j-core:2.23.1",
"url": "https://repo.maven.apache.org/maven2"
}
],
"mainClass": "dev.frogmc.frogloader.impl.launch.client.FrogClient",
"type": "snapshot"
}

View file

@ -1,5 +1,9 @@
import dev.frogmc.phytotelma.ext.minecraft
import dev.frogmc.phytotelma.ext.loader
plugins {
alias(libs.plugins.phytotelma)
id("java")
id("dev.frogmc.phytotelma").version("$phytotelma_version")
}
group = "$maven_group"
@ -9,21 +13,7 @@ repositories {
}
dependencies {
}
phytotelma {
minecraft {
version = project.libs.versions.minecraft
}
loader {
version = project.libs.versions.frogloader
}
froglib {
version = project.libs.versions.froglib
}
}
minecraft(libs.versions.minecraft).loader(libs.versions.loader)
java {
sourceCompatibility = JavaVersion.VERSION_21

View file

@ -1,16 +1,9 @@
[versions]
phytotelma = "$phytotelma_version"
minecraft = "$game_version"
frogloader = "$loader_version"
froglib = "$froglib_version"
loader = "$loader_version"
[libraries]
# technically unused
minecraft = { module = "com.mojang:minecraft", version.ref = "minecraft" }
frogloader = { module = "dev.frogmc:frogloader", version.ref = "frogloader" }
froglib = { module = "dev.frogmc:froglib", version.ref = "froglib" }
[plugins]
phytotelma = { id = "dev.frogmc.phytotelma", version.ref = "phytotelma" }
loader = { module = "dev.frogmc:frogloader", version.ref = "loader" }

View file

@ -1,6 +1,6 @@
#Mon May 13 10:13:59 CEST 2024
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

0
public/resources/template/gradlew.bat vendored Executable file → Normal file
View file

View file

@ -3,7 +3,7 @@ package $maven_group.$mod_id;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import dev.frogmc.froglib.entrypoints.api.MainExtension;
import dev.frogmc.froglib.entrypoints.MainExtension;
import dev.frogmc.frogloader.api.mod.ModProperties;
public class $mod_name_pascalMain implements MainExtension {

View file

@ -3,9 +3,6 @@
"minVersion": "0.8",
"package": "$maven_group.mixin",
"compatibilityLevel": "JAVA_21",
"mixins": [
],
"server": [
],

View file

@ -17,5 +17,5 @@ depends = [
]
[frog.extensions]
mixin = "$mod_id.mixins.json"
mixin_config = "$mod_id.mixins.json"
main = "$maven_group.$mod_name_pascalMain"

View file

@ -0,0 +1,258 @@
import {
useMediaQuery
} from "./chunk-F5V7BSZ2.js";
import {
computed,
ref,
shallowRef,
watch
} from "./chunk-SSC5OD6V.js";
// ../node_modules/vitepress/dist/client/theme-default/index.js
import "/home/lilly/Documents/Projects/frogmc/frogmc.dev/node_modules/vitepress/dist/client/theme-default/styles/fonts.css";
// ../node_modules/vitepress/dist/client/theme-default/without-fonts.js
import "/home/lilly/Documents/Projects/frogmc/frogmc.dev/node_modules/vitepress/dist/client/theme-default/styles/vars.css";
import "/home/lilly/Documents/Projects/frogmc/frogmc.dev/node_modules/vitepress/dist/client/theme-default/styles/base.css";
import "/home/lilly/Documents/Projects/frogmc/frogmc.dev/node_modules/vitepress/dist/client/theme-default/styles/icons.css";
import "/home/lilly/Documents/Projects/frogmc/frogmc.dev/node_modules/vitepress/dist/client/theme-default/styles/utils.css";
import "/home/lilly/Documents/Projects/frogmc/frogmc.dev/node_modules/vitepress/dist/client/theme-default/styles/components/custom-block.css";
import "/home/lilly/Documents/Projects/frogmc/frogmc.dev/node_modules/vitepress/dist/client/theme-default/styles/components/vp-code.css";
import "/home/lilly/Documents/Projects/frogmc/frogmc.dev/node_modules/vitepress/dist/client/theme-default/styles/components/vp-code-group.css";
import "/home/lilly/Documents/Projects/frogmc/frogmc.dev/node_modules/vitepress/dist/client/theme-default/styles/components/vp-doc.css";
import "/home/lilly/Documents/Projects/frogmc/frogmc.dev/node_modules/vitepress/dist/client/theme-default/styles/components/vp-sponsor.css";
import VPBadge from "/home/lilly/Documents/Projects/frogmc/frogmc.dev/node_modules/vitepress/dist/client/theme-default/components/VPBadge.vue";
import Layout from "/home/lilly/Documents/Projects/frogmc/frogmc.dev/node_modules/vitepress/dist/client/theme-default/Layout.vue";
import { default as default2 } from "/home/lilly/Documents/Projects/frogmc/frogmc.dev/node_modules/vitepress/dist/client/theme-default/components/VPBadge.vue";
import { default as default3 } from "/home/lilly/Documents/Projects/frogmc/frogmc.dev/node_modules/vitepress/dist/client/theme-default/components/VPImage.vue";
import { default as default4 } from "/home/lilly/Documents/Projects/frogmc/frogmc.dev/node_modules/vitepress/dist/client/theme-default/components/VPButton.vue";
import { default as default5 } from "/home/lilly/Documents/Projects/frogmc/frogmc.dev/node_modules/vitepress/dist/client/theme-default/components/VPHomeHero.vue";
import { default as default6 } from "/home/lilly/Documents/Projects/frogmc/frogmc.dev/node_modules/vitepress/dist/client/theme-default/components/VPHomeFeatures.vue";
import { default as default7 } from "/home/lilly/Documents/Projects/frogmc/frogmc.dev/node_modules/vitepress/dist/client/theme-default/components/VPHomeSponsors.vue";
import { default as default8 } from "/home/lilly/Documents/Projects/frogmc/frogmc.dev/node_modules/vitepress/dist/client/theme-default/components/VPDocAsideSponsors.vue";
import { default as default9 } from "/home/lilly/Documents/Projects/frogmc/frogmc.dev/node_modules/vitepress/dist/client/theme-default/components/VPSponsors.vue";
import { default as default10 } from "/home/lilly/Documents/Projects/frogmc/frogmc.dev/node_modules/vitepress/dist/client/theme-default/components/VPTeamPage.vue";
import { default as default11 } from "/home/lilly/Documents/Projects/frogmc/frogmc.dev/node_modules/vitepress/dist/client/theme-default/components/VPTeamPageTitle.vue";
import { default as default12 } from "/home/lilly/Documents/Projects/frogmc/frogmc.dev/node_modules/vitepress/dist/client/theme-default/components/VPTeamPageSection.vue";
import { default as default13 } from "/home/lilly/Documents/Projects/frogmc/frogmc.dev/node_modules/vitepress/dist/client/theme-default/components/VPTeamMembers.vue";
// ../node_modules/vitepress/dist/client/theme-default/support/utils.js
import { withBase } from "vitepress";
// ../node_modules/vitepress/dist/client/theme-default/composables/data.js
import { useData as useData$ } from "vitepress";
var useData = useData$;
// ../node_modules/vitepress/dist/client/theme-default/support/utils.js
function ensureStartingSlash(path) {
return /^\//.test(path) ? path : `/${path}`;
}
// ../node_modules/vitepress/dist/client/theme-default/support/sidebar.js
function getSidebar(_sidebar, path) {
if (Array.isArray(_sidebar))
return addBase(_sidebar);
if (_sidebar == null)
return [];
path = ensureStartingSlash(path);
const dir = Object.keys(_sidebar).sort((a, b) => {
return b.split("/").length - a.split("/").length;
}).find((dir2) => {
return path.startsWith(ensureStartingSlash(dir2));
});
const sidebar = dir ? _sidebar[dir] : [];
return Array.isArray(sidebar) ? addBase(sidebar) : addBase(sidebar.items, sidebar.base);
}
function getSidebarGroups(sidebar) {
const groups = [];
let lastGroupIndex = 0;
for (const index in sidebar) {
const item = sidebar[index];
if (item.items) {
lastGroupIndex = groups.push(item);
continue;
}
if (!groups[lastGroupIndex]) {
groups.push({ items: [] });
}
groups[lastGroupIndex].items.push(item);
}
return groups;
}
function addBase(items, _base) {
return [...items].map((_item) => {
const item = { ..._item };
const base = item.base || _base;
if (base && item.link)
item.link = base + item.link;
if (item.items)
item.items = addBase(item.items, base);
return item;
});
}
// ../node_modules/vitepress/dist/client/theme-default/composables/sidebar.js
function useSidebar() {
const { frontmatter, page, theme: theme2 } = useData();
const is960 = useMediaQuery("(min-width: 960px)");
const isOpen = ref(false);
const _sidebar = computed(() => {
const sidebarConfig = theme2.value.sidebar;
const relativePath = page.value.relativePath;
return sidebarConfig ? getSidebar(sidebarConfig, relativePath) : [];
});
const sidebar = ref(_sidebar.value);
watch(_sidebar, (next, prev) => {
if (JSON.stringify(next) !== JSON.stringify(prev))
sidebar.value = _sidebar.value;
});
const hasSidebar = computed(() => {
return frontmatter.value.sidebar !== false && sidebar.value.length > 0 && frontmatter.value.layout !== "home";
});
const leftAside = computed(() => {
if (hasAside)
return frontmatter.value.aside == null ? theme2.value.aside === "left" : frontmatter.value.aside === "left";
return false;
});
const hasAside = computed(() => {
if (frontmatter.value.layout === "home")
return false;
if (frontmatter.value.aside != null)
return !!frontmatter.value.aside;
return theme2.value.aside !== false;
});
const isSidebarEnabled = computed(() => hasSidebar.value && is960.value);
const sidebarGroups = computed(() => {
return hasSidebar.value ? getSidebarGroups(sidebar.value) : [];
});
function open() {
isOpen.value = true;
}
function close() {
isOpen.value = false;
}
function toggle() {
isOpen.value ? close() : open();
}
return {
isOpen,
sidebar,
sidebarGroups,
hasSidebar,
hasAside,
leftAside,
isSidebarEnabled,
open,
close,
toggle
};
}
// ../node_modules/vitepress/dist/client/theme-default/composables/local-nav.js
import { onContentUpdated } from "vitepress";
// ../node_modules/vitepress/dist/client/theme-default/composables/outline.js
import { getScrollOffset } from "vitepress";
var resolvedHeaders = [];
function getHeaders(range) {
const headers = [
...document.querySelectorAll(".VPDoc :where(h1,h2,h3,h4,h5,h6)")
].filter((el) => el.id && el.hasChildNodes()).map((el) => {
const level = Number(el.tagName[1]);
return {
element: el,
title: serializeHeader(el),
link: "#" + el.id,
level
};
});
return resolveHeaders(headers, range);
}
function serializeHeader(h) {
let ret = "";
for (const node of h.childNodes) {
if (node.nodeType === 1) {
if (node.classList.contains("VPBadge") || node.classList.contains("header-anchor") || node.classList.contains("ignore-header")) {
continue;
}
ret += node.textContent;
} else if (node.nodeType === 3) {
ret += node.textContent;
}
}
return ret.trim();
}
function resolveHeaders(headers, range) {
if (range === false) {
return [];
}
const levelsRange = (typeof range === "object" && !Array.isArray(range) ? range.level : range) || 2;
const [high, low] = typeof levelsRange === "number" ? [levelsRange, levelsRange] : levelsRange === "deep" ? [2, 6] : levelsRange;
headers = headers.filter((h) => h.level >= high && h.level <= low);
resolvedHeaders.length = 0;
for (const { element, link } of headers) {
resolvedHeaders.push({ element, link });
}
const ret = [];
outer:
for (let i = 0; i < headers.length; i++) {
const cur = headers[i];
if (i === 0) {
ret.push(cur);
} else {
for (let j = i - 1; j >= 0; j--) {
const prev = headers[j];
if (prev.level < cur.level) {
;
(prev.children || (prev.children = [])).push(cur);
continue outer;
}
}
ret.push(cur);
}
}
return ret;
}
// ../node_modules/vitepress/dist/client/theme-default/composables/local-nav.js
function useLocalNav() {
const { theme: theme2, frontmatter } = useData();
const headers = shallowRef([]);
const hasLocalNav = computed(() => {
return headers.value.length > 0;
});
onContentUpdated(() => {
headers.value = getHeaders(frontmatter.value.outline ?? theme2.value.outline);
});
return {
headers,
hasLocalNav
};
}
// ../node_modules/vitepress/dist/client/theme-default/without-fonts.js
var theme = {
Layout,
enhanceApp: ({ app }) => {
app.component("Badge", VPBadge);
}
};
var without_fonts_default = theme;
export {
default2 as VPBadge,
default4 as VPButton,
default8 as VPDocAsideSponsors,
default6 as VPHomeFeatures,
default5 as VPHomeHero,
default7 as VPHomeSponsors,
default3 as VPImage,
default9 as VPSponsors,
default13 as VPTeamMembers,
default10 as VPTeamPage,
default12 as VPTeamPageSection,
default11 as VPTeamPageTitle,
without_fonts_default as default,
useLocalNav,
useSidebar
};
//# sourceMappingURL=@theme_index.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,40 @@
{
"hash": "93d13ac2",
"configHash": "5f5a549a",
"lockfileHash": "dbbecdc7",
"browserHash": "c0d9839c",
"optimized": {
"vue": {
"src": "../../../../node_modules/vue/dist/vue.runtime.esm-bundler.js",
"file": "vue.js",
"fileHash": "2ad6cbad",
"needsInterop": false
},
"vitepress > @vue/devtools-api": {
"src": "../../../../node_modules/@vue/devtools-api/dist/index.js",
"file": "vitepress___@vue_devtools-api.js",
"fileHash": "9a313f90",
"needsInterop": false
},
"vitepress > @vueuse/core": {
"src": "../../../../node_modules/@vueuse/core/index.mjs",
"file": "vitepress___@vueuse_core.js",
"fileHash": "1333a041",
"needsInterop": false
},
"@theme/index": {
"src": "../../../../node_modules/vitepress/dist/client/theme-default/index.js",
"file": "@theme_index.js",
"fileHash": "e956a3a6",
"needsInterop": false
}
},
"chunks": {
"chunk-F5V7BSZ2": {
"file": "chunk-F5V7BSZ2.js"
},
"chunk-SSC5OD6V": {
"file": "chunk-SSC5OD6V.js"
}
}
}

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,3 @@
{
"type": "module"
}

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,567 @@
import {
DefaultMagicKeysAliasMap,
StorageSerializers,
TransitionPresets,
assert,
breakpointsAntDesign,
breakpointsBootstrapV5,
breakpointsMasterCss,
breakpointsPrimeFlex,
breakpointsQuasar,
breakpointsSematic,
breakpointsTailwind,
breakpointsVuetify,
breakpointsVuetifyV2,
breakpointsVuetifyV3,
bypassFilter,
camelize,
clamp,
cloneFnJSON,
computedAsync,
computedEager,
computedInject,
computedWithControl,
containsProp,
controlledRef,
createEventHook,
createFetch,
createFilterWrapper,
createGlobalState,
createInjectionState,
createReusableTemplate,
createSharedComposable,
createSingletonPromise,
createTemplatePromise,
createUnrefFn,
customStorageEventName,
debounceFilter,
defaultDocument,
defaultLocation,
defaultNavigator,
defaultWindow,
directiveHooks,
executeTransition,
extendRef,
formatDate,
formatTimeAgo,
get,
getLifeCycleTarget,
getSSRHandler,
hasOwn,
hyphenate,
identity,
increaseWithUnit,
injectLocal,
invoke,
isClient,
isDef,
isDefined,
isIOS,
isObject,
isWorker,
makeDestructurable,
mapGamepadToXbox360Controller,
noop,
normalizeDate,
notNullish,
now,
objectEntries,
objectOmit,
objectPick,
onClickOutside,
onKeyDown,
onKeyPressed,
onKeyStroke,
onKeyUp,
onLongPress,
onStartTyping,
pausableFilter,
promiseTimeout,
provideLocal,
rand,
reactify,
reactifyObject,
reactiveComputed,
reactiveOmit,
reactivePick,
refAutoReset,
refDebounced,
refDefault,
refThrottled,
refWithControl,
resolveRef,
resolveUnref,
set,
setSSRHandler,
syncRef,
syncRefs,
templateRef,
throttleFilter,
timestamp,
toReactive,
toRef,
toRefs,
toValue,
tryOnBeforeMount,
tryOnBeforeUnmount,
tryOnMounted,
tryOnScopeDispose,
tryOnUnmounted,
unrefElement,
until,
useActiveElement,
useAnimate,
useArrayDifference,
useArrayEvery,
useArrayFilter,
useArrayFind,
useArrayFindIndex,
useArrayFindLast,
useArrayIncludes,
useArrayJoin,
useArrayMap,
useArrayReduce,
useArraySome,
useArrayUnique,
useAsyncQueue,
useAsyncState,
useBase64,
useBattery,
useBluetooth,
useBreakpoints,
useBroadcastChannel,
useBrowserLocation,
useCached,
useClipboard,
useClipboardItems,
useCloned,
useColorMode,
useConfirmDialog,
useCounter,
useCssVar,
useCurrentElement,
useCycleList,
useDark,
useDateFormat,
useDebounceFn,
useDebouncedRefHistory,
useDeviceMotion,
useDeviceOrientation,
useDevicePixelRatio,
useDevicesList,
useDisplayMedia,
useDocumentVisibility,
useDraggable,
useDropZone,
useElementBounding,
useElementByPoint,
useElementHover,
useElementSize,
useElementVisibility,
useEventBus,
useEventListener,
useEventSource,
useEyeDropper,
useFavicon,
useFetch,
useFileDialog,
useFileSystemAccess,
useFocus,
useFocusWithin,
useFps,
useFullscreen,
useGamepad,
useGeolocation,
useIdle,
useImage,
useInfiniteScroll,
useIntersectionObserver,
useInterval,
useIntervalFn,
useKeyModifier,
useLastChanged,
useLocalStorage,
useMagicKeys,
useManualRefHistory,
useMediaControls,
useMediaQuery,
useMemoize,
useMemory,
useMounted,
useMouse,
useMouseInElement,
useMousePressed,
useMutationObserver,
useNavigatorLanguage,
useNetwork,
useNow,
useObjectUrl,
useOffsetPagination,
useOnline,
usePageLeave,
useParallax,
useParentElement,
usePerformanceObserver,
usePermission,
usePointer,
usePointerLock,
usePointerSwipe,
usePreferredColorScheme,
usePreferredContrast,
usePreferredDark,
usePreferredLanguages,
usePreferredReducedMotion,
usePrevious,
useRafFn,
useRefHistory,
useResizeObserver,
useScreenOrientation,
useScreenSafeArea,
useScriptTag,
useScroll,
useScrollLock,
useSessionStorage,
useShare,
useSorted,
useSpeechRecognition,
useSpeechSynthesis,
useStepper,
useStorage,
useStorageAsync,
useStyleTag,
useSupported,
useSwipe,
useTemplateRefsList,
useTextDirection,
useTextSelection,
useTextareaAutosize,
useThrottleFn,
useThrottledRefHistory,
useTimeAgo,
useTimeout,
useTimeoutFn,
useTimeoutPoll,
useTimestamp,
useTitle,
useToNumber,
useToString,
useToggle,
useTransition,
useUrlSearchParams,
useUserMedia,
useVModel,
useVModels,
useVibrate,
useVirtualList,
useWakeLock,
useWebNotification,
useWebSocket,
useWebWorker,
useWebWorkerFn,
useWindowFocus,
useWindowScroll,
useWindowSize,
watchArray,
watchAtMost,
watchDebounced,
watchDeep,
watchIgnorable,
watchImmediate,
watchOnce,
watchPausable,
watchThrottled,
watchTriggerable,
watchWithFilter,
whenever
} from "./chunk-F5V7BSZ2.js";
import "./chunk-SSC5OD6V.js";
export {
DefaultMagicKeysAliasMap,
StorageSerializers,
TransitionPresets,
assert,
computedAsync as asyncComputed,
refAutoReset as autoResetRef,
breakpointsAntDesign,
breakpointsBootstrapV5,
breakpointsMasterCss,
breakpointsPrimeFlex,
breakpointsQuasar,
breakpointsSematic,
breakpointsTailwind,
breakpointsVuetify,
breakpointsVuetifyV2,
breakpointsVuetifyV3,
bypassFilter,
camelize,
clamp,
cloneFnJSON,
computedAsync,
computedEager,
computedInject,
computedWithControl,
containsProp,
computedWithControl as controlledComputed,
controlledRef,
createEventHook,
createFetch,
createFilterWrapper,
createGlobalState,
createInjectionState,
reactify as createReactiveFn,
createReusableTemplate,
createSharedComposable,
createSingletonPromise,
createTemplatePromise,
createUnrefFn,
customStorageEventName,
debounceFilter,
refDebounced as debouncedRef,
watchDebounced as debouncedWatch,
defaultDocument,
defaultLocation,
defaultNavigator,
defaultWindow,
directiveHooks,
computedEager as eagerComputed,
executeTransition,
extendRef,
formatDate,
formatTimeAgo,
get,
getLifeCycleTarget,
getSSRHandler,
hasOwn,
hyphenate,
identity,
watchIgnorable as ignorableWatch,
increaseWithUnit,
injectLocal,
invoke,
isClient,
isDef,
isDefined,
isIOS,
isObject,
isWorker,
makeDestructurable,
mapGamepadToXbox360Controller,
noop,
normalizeDate,
notNullish,
now,
objectEntries,
objectOmit,
objectPick,
onClickOutside,
onKeyDown,
onKeyPressed,
onKeyStroke,
onKeyUp,
onLongPress,
onStartTyping,
pausableFilter,
watchPausable as pausableWatch,
promiseTimeout,
provideLocal,
rand,
reactify,
reactifyObject,
reactiveComputed,
reactiveOmit,
reactivePick,
refAutoReset,
refDebounced,
refDefault,
refThrottled,
refWithControl,
resolveRef,
resolveUnref,
set,
setSSRHandler,
syncRef,
syncRefs,
templateRef,
throttleFilter,
refThrottled as throttledRef,
watchThrottled as throttledWatch,
timestamp,
toReactive,
toRef,
toRefs,
toValue,
tryOnBeforeMount,
tryOnBeforeUnmount,
tryOnMounted,
tryOnScopeDispose,
tryOnUnmounted,
unrefElement,
until,
useActiveElement,
useAnimate,
useArrayDifference,
useArrayEvery,
useArrayFilter,
useArrayFind,
useArrayFindIndex,
useArrayFindLast,
useArrayIncludes,
useArrayJoin,
useArrayMap,
useArrayReduce,
useArraySome,
useArrayUnique,
useAsyncQueue,
useAsyncState,
useBase64,
useBattery,
useBluetooth,
useBreakpoints,
useBroadcastChannel,
useBrowserLocation,
useCached,
useClipboard,
useClipboardItems,
useCloned,
useColorMode,
useConfirmDialog,
useCounter,
useCssVar,
useCurrentElement,
useCycleList,
useDark,
useDateFormat,
refDebounced as useDebounce,
useDebounceFn,
useDebouncedRefHistory,
useDeviceMotion,
useDeviceOrientation,
useDevicePixelRatio,
useDevicesList,
useDisplayMedia,
useDocumentVisibility,
useDraggable,
useDropZone,
useElementBounding,
useElementByPoint,
useElementHover,
useElementSize,
useElementVisibility,
useEventBus,
useEventListener,
useEventSource,
useEyeDropper,
useFavicon,
useFetch,
useFileDialog,
useFileSystemAccess,
useFocus,
useFocusWithin,
useFps,
useFullscreen,
useGamepad,
useGeolocation,
useIdle,
useImage,
useInfiniteScroll,
useIntersectionObserver,
useInterval,
useIntervalFn,
useKeyModifier,
useLastChanged,
useLocalStorage,
useMagicKeys,
useManualRefHistory,
useMediaControls,
useMediaQuery,
useMemoize,
useMemory,
useMounted,
useMouse,
useMouseInElement,
useMousePressed,
useMutationObserver,
useNavigatorLanguage,
useNetwork,
useNow,
useObjectUrl,
useOffsetPagination,
useOnline,
usePageLeave,
useParallax,
useParentElement,
usePerformanceObserver,
usePermission,
usePointer,
usePointerLock,
usePointerSwipe,
usePreferredColorScheme,
usePreferredContrast,
usePreferredDark,
usePreferredLanguages,
usePreferredReducedMotion,
usePrevious,
useRafFn,
useRefHistory,
useResizeObserver,
useScreenOrientation,
useScreenSafeArea,
useScriptTag,
useScroll,
useScrollLock,
useSessionStorage,
useShare,
useSorted,
useSpeechRecognition,
useSpeechSynthesis,
useStepper,
useStorage,
useStorageAsync,
useStyleTag,
useSupported,
useSwipe,
useTemplateRefsList,
useTextDirection,
useTextSelection,
useTextareaAutosize,
refThrottled as useThrottle,
useThrottleFn,
useThrottledRefHistory,
useTimeAgo,
useTimeout,
useTimeoutFn,
useTimeoutPoll,
useTimestamp,
useTitle,
useToNumber,
useToString,
useToggle,
useTransition,
useUrlSearchParams,
useUserMedia,
useVModel,
useVModels,
useVibrate,
useVirtualList,
useWakeLock,
useWebNotification,
useWebSocket,
useWebWorker,
useWebWorkerFn,
useWindowFocus,
useWindowScroll,
useWindowSize,
watchArray,
watchAtMost,
watchDebounced,
watchDeep,
watchIgnorable,
watchImmediate,
watchOnce,
watchPausable,
watchThrottled,
watchTriggerable,
watchWithFilter,
whenever
};
//# sourceMappingURL=vitepress___@vueuse_core.js.map

View file

@ -0,0 +1,7 @@
{
"version": 3,
"sources": [],
"sourcesContent": [],
"mappings": "",
"names": []
}

323
spec/.vitepress/cache/deps/vue.js vendored Normal file
View file

@ -0,0 +1,323 @@
import {
BaseTransition,
BaseTransitionPropsValidators,
Comment,
DeprecationTypes,
EffectScope,
ErrorCodes,
ErrorTypeStrings,
Fragment,
KeepAlive,
ReactiveEffect,
Static,
Suspense,
Teleport,
Text,
TrackOpTypes,
Transition,
TransitionGroup,
TriggerOpTypes,
VueElement,
assertNumber,
callWithAsyncErrorHandling,
callWithErrorHandling,
camelize,
capitalize,
cloneVNode,
compatUtils,
compile,
computed,
createApp,
createBaseVNode,
createBlock,
createCommentVNode,
createElementBlock,
createHydrationRenderer,
createPropsRestProxy,
createRenderer,
createSSRApp,
createSlots,
createStaticVNode,
createTextVNode,
createVNode,
customRef,
defineAsyncComponent,
defineComponent,
defineCustomElement,
defineEmits,
defineExpose,
defineModel,
defineOptions,
defineProps,
defineSSRCustomElement,
defineSlots,
devtools,
effect,
effectScope,
getCurrentInstance,
getCurrentScope,
getTransitionRawChildren,
guardReactiveProps,
h,
handleError,
hasInjectionContext,
hydrate,
initCustomFormatter,
initDirectivesForSSR,
inject,
isMemoSame,
isProxy,
isReactive,
isReadonly,
isRef,
isRuntimeOnly,
isShallow,
isVNode,
markRaw,
mergeDefaults,
mergeModels,
mergeProps,
nextTick,
normalizeClass,
normalizeProps,
normalizeStyle,
onActivated,
onBeforeMount,
onBeforeUnmount,
onBeforeUpdate,
onDeactivated,
onErrorCaptured,
onMounted,
onRenderTracked,
onRenderTriggered,
onScopeDispose,
onServerPrefetch,
onUnmounted,
onUpdated,
openBlock,
popScopeId,
provide,
proxyRefs,
pushScopeId,
queuePostFlushCb,
reactive,
readonly,
ref,
registerRuntimeCompiler,
render,
renderList,
renderSlot,
resolveComponent,
resolveDirective,
resolveDynamicComponent,
resolveFilter,
resolveTransitionHooks,
setBlockTracking,
setDevtoolsHook,
setTransitionHooks,
shallowReactive,
shallowReadonly,
shallowRef,
ssrContextKey,
ssrUtils,
stop,
toDisplayString,
toHandlerKey,
toHandlers,
toRaw,
toRef,
toRefs,
toValue,
transformVNodeArgs,
triggerRef,
unref,
useAttrs,
useCssModule,
useCssVars,
useModel,
useSSRContext,
useSlots,
useTransitionState,
vModelCheckbox,
vModelDynamic,
vModelRadio,
vModelSelect,
vModelText,
vShow,
version,
warn,
watch,
watchEffect,
watchPostEffect,
watchSyncEffect,
withAsyncContext,
withCtx,
withDefaults,
withDirectives,
withKeys,
withMemo,
withModifiers,
withScopeId
} from "./chunk-SSC5OD6V.js";
export {
BaseTransition,
BaseTransitionPropsValidators,
Comment,
DeprecationTypes,
EffectScope,
ErrorCodes,
ErrorTypeStrings,
Fragment,
KeepAlive,
ReactiveEffect,
Static,
Suspense,
Teleport,
Text,
TrackOpTypes,
Transition,
TransitionGroup,
TriggerOpTypes,
VueElement,
assertNumber,
callWithAsyncErrorHandling,
callWithErrorHandling,
camelize,
capitalize,
cloneVNode,
compatUtils,
compile,
computed,
createApp,
createBlock,
createCommentVNode,
createElementBlock,
createBaseVNode as createElementVNode,
createHydrationRenderer,
createPropsRestProxy,
createRenderer,
createSSRApp,
createSlots,
createStaticVNode,
createTextVNode,
createVNode,
customRef,
defineAsyncComponent,
defineComponent,
defineCustomElement,
defineEmits,
defineExpose,
defineModel,
defineOptions,
defineProps,
defineSSRCustomElement,
defineSlots,
devtools,
effect,
effectScope,
getCurrentInstance,
getCurrentScope,
getTransitionRawChildren,
guardReactiveProps,
h,
handleError,
hasInjectionContext,
hydrate,
initCustomFormatter,
initDirectivesForSSR,
inject,
isMemoSame,
isProxy,
isReactive,
isReadonly,
isRef,
isRuntimeOnly,
isShallow,
isVNode,
markRaw,
mergeDefaults,
mergeModels,
mergeProps,
nextTick,
normalizeClass,
normalizeProps,
normalizeStyle,
onActivated,
onBeforeMount,
onBeforeUnmount,
onBeforeUpdate,
onDeactivated,
onErrorCaptured,
onMounted,
onRenderTracked,
onRenderTriggered,
onScopeDispose,
onServerPrefetch,
onUnmounted,
onUpdated,
openBlock,
popScopeId,
provide,
proxyRefs,
pushScopeId,
queuePostFlushCb,
reactive,
readonly,
ref,
registerRuntimeCompiler,
render,
renderList,
renderSlot,
resolveComponent,
resolveDirective,
resolveDynamicComponent,
resolveFilter,
resolveTransitionHooks,
setBlockTracking,
setDevtoolsHook,
setTransitionHooks,
shallowReactive,
shallowReadonly,
shallowRef,
ssrContextKey,
ssrUtils,
stop,
toDisplayString,
toHandlerKey,
toHandlers,
toRaw,
toRef,
toRefs,
toValue,
transformVNodeArgs,
triggerRef,
unref,
useAttrs,
useCssModule,
useCssVars,
useModel,
useSSRContext,
useSlots,
useTransitionState,
vModelCheckbox,
vModelDynamic,
vModelRadio,
vModelSelect,
vModelText,
vShow,
version,
warn,
watch,
watchEffect,
watchPostEffect,
watchSyncEffect,
withAsyncContext,
withCtx,
withDefaults,
withDirectives,
withKeys,
withMemo,
withModifiers,
withScopeId
};
//# sourceMappingURL=vue.js.map

7
spec/.vitepress/cache/deps/vue.js.map vendored Normal file
View file

@ -0,0 +1,7 @@
{
"version": 3,
"sources": [],
"sourcesContent": [],
"mappings": "",
"names": []
}

View file

@ -1,4 +0,0 @@
# AccessWidener Specification

View file

@ -1,22 +1,63 @@
# frog.mod.toml Specification
### Full Example
**frog.mod.toml** is a file containing metadata related to your mod in frog. It is quite similar to the metadata formats of other mod loaders, however it is reorganized to be less cluttered. It is in the [TOML](https://toml.io/) format, and this document will use the grammar of that format.
#### `[frog]`
The `[frog]` table contains information about this metadata file.
- `format_version`: the format version of this frog.mod.toml file. The current format version is 1.0.0.
#### `[frog.mod]`
The `[frog.mod]` table contains information about your mod.
- `id`: your mods namespace id. Should be alphanumeric without spaces, and all lowercase.
- `name`: the formatted name of your mod. Optional but strongly recommended.
- `version`: the version of your mod. Should respect the [SemVer](https://semver.org/) specification.
- `license`: the license of your mod. Should be either an [SPDX License Identifier](https://spdx.org/licenses/) or a hyperlink to your license. Optional but recommended.
- `credits`: the credits of your mod. Should be made up of [Person](#Person) inline tables. Optional but recommended.
##### Person
The Person inline table identifies someone associated with your mod. It contains the following fields:
- `name`: The name of the person. Can be any string.
- `roles`: The roles of the person in the project. Should be an array of strings. <!---TODO: translatable roles in mod menu-->
#### `[frog.dependencies]`
The `[frog.dependencies]` table contains information about this mod's dependencies, as well as mod incompatibilities. `depends`, `breaks`, `suggests`, and `provides` are all arrays of [Mod](#Mod) inline tables.
##### Mod
The Mod inline table contains information referencing a mod other than your own. It contains the following fields:
- `id`: the other mods namespace id. Should be alphanumeric without spaces and all lowercase, unless the source mod isn't.
- `versions`: the range of versions of the other mod that your mod requires. Should be a SemVer version, or a range of SemVer versions (see [this](https://github.com/npm/node-semver#ranges) for a more detailed specification on SemVer ranges). If any version is acceptable, can also be set to `*`. **Use only in `depends`, `breaks`, and `suggests` arrays!**
- `version`: a single version of another mod. Should be a SemVer version. **Use only in `provides` array!**
- `name`: the formatted name of the required mod. Optional.
- `link`: a link to the download page of the mod. Mods from certain sites may be able to be handled specially by frog loader. Optional.
#### `[frog.extensions]`
The `[frog.extensions]` table contains information on definitions that modify the behavior of the loader or game. It can contain the following fields:
- `mixin`: reference to a `.mixins.json` file contained within the `src/resources` folder. See [Mixin](/exts/mixin).
- `accesswidener`: reference to a `.accesswidener` file contained within the `src/resources` folder. See [AccessWidener](/exts/aw).
- `prelaunch`: reference to a PreLaunch class on the classpath, separated by forward slashes. See [PreLaunch](/exts/prelaunch).
- `init`: reference to a MainExtension entrypoint on the classpath, separated by forward slashes. See [MainExtension](/exts/entrypoints#MainExtension).
- `client`: reference to a ClientExtension entrypoint on the classpath, separated by forward slashes. See [ClientExtension](/exts/entrypoints#ClientExtension).
- `server`: reference to a ServerExtension entrypoint on the classpath, separated by forward slashes. See [ServerExtension](/exts/entrypoints#ServerExtension).
#### Internal Keys
The `included_jars` and `phytotelma.generated` keys are inserted by the [Phytotelma](/contributing/tools#phytotelma) tool and should not be edited manually.
### Full Example
The following is an example of a complete well-formated frog.mod.toml file.
```toml
[frog]
format_version = "1.0.0" # the version of this file format
format_version = "1.0.0"
[frog.mod]
id = "example_mod" # Your mod's id
name = "Example Mod"# The name of your mod
version = "1.0.0" # the mod version, must respect SemVer
license = "CC0-1.0" # License (SPDX Format recommended)
credits = [ # List of Person declarations
id = "example_mod"
name = "Example Mod"
version = "1.0.0"
license = "CC0-1.0"
credits = [
{ name = "You", roles = ["author", "other_role"] }
]
[frog.dependencies] # Dependency declarations
# For all dependencies only the id and version (range) are required.
[frog.dependencies]
depends = [
{ id = "other_mod", versions = ">=0.2.0", name = "Other Mod", link = "https://modrinth.com/mod/<slug>" }
]
@ -27,21 +68,20 @@ suggests = [
{ id = "frogloader", versions = "*" }
]
provides = [
{ id = "provided_mod", version = "2.0.0" } # note: provides does not support version ranges, only a single version!
{ id = "provided_mod", version = "2.0.0" }
]
[frog.extensions] # key-value pairs for whatever else is needed (Entrypoints, custom values, lists of files, indicators...)
[frog.extensions]
mixin = "example_mod.mixins.json"
accesswidener = "example_mod.accesswidener"
prelaunch = "com.example.frog.PreLaunch"
loading_type = "required" # the type 'required' is implicit if it isn't present. Other values are not specified, but using 'optional' is recommended.
```
These keys are automatically inserted by [Phytotelma](/contributing/tools#phytotelma) for generated metadata files and their host mods respectively.
You should never need to insert them yourself.
```toml
included_jars = [[
prelaunch = "com/example/frog/PreLaunch"
init = "com/example/frog/FrogInit"
client = "com/example/frog/client/FrogClientInit"
server = "com/example/frog/server/FrogServerInit"
included_jars = [
{ id = "mod_id", path = "META-INF/jars/mod.jar" }
]]
]
phytotelma.generated = true
```

View file

@ -1 +0,0 @@
# Mixin Config Specification

View file

@ -22,95 +22,66 @@ outline: false
const licenseRef = ref()
const useSnapshots = ref()
let releases = []
let snapshots = []
let versions = []
let latestLoader
let latestPhytotelma
let latestFrogLib
let latestLoaderSnapshot
let latestPhytotelmaSnapshot
let latestFrogLibSnapshot
async function getGameVersions() {
const response = await fetch("https://piston-meta.mojang.com/mc/game/version_manifest_v2.json")
return await response.json()
}
async function getVersions() {
let optionString = ""
function getVersions() {
versionSelector.value.innerHTML = ""
for (let version of releases) {
versionSelector.value.innerHTML += "<option value=\""+version.id+"\">"+version.id+"</option>"
}
if (showSnapshots.value) {
for (let version of versions) {
optionString += "<option value=\""+version.id+"\">"+version.id+"</option>"
}
} else {
for (let version of releases) {
optionString += "<option value=\""+version.id+"\">"+version.id+"</option>"
for (let version of snapshots) {
versionSelector.value.innerHTML += "<option value=\""+version.id+"\">"+version.id+"</option>"
}
}
versionSelector.value.innerHTML = optionString
}
onMounted(() => {
Promise.all([
getGameVersions().then((v) => {
versions = v.versions
for (let version of versions){
if (version.type === "release"){
releases.push(version)
}
getGameVersions().then((v) => {
versions = v.versions
for (let version of versions){
if (version.type === "snapshot"){
snapshots.push(version)
} else {
releases.push(version)
}
getVersions()
}),
getLatestProjectVersions()
]).then((unused) => {
let button = document.getElementById("generate")
button.innerHTML = "Download"
button.disabled = false
}
getVersions()
})
getLatestProjectVersions()
})
function getLatestProjectVersions() {
return Promise.all([
fetchVersionFromMaven("releases", "frogloader").then((v) => {
latestLoader = v
document.getElementById("frogLoaderVersionReleaseBadge").innerHTML = v
}).catch((err) => {
document.getElementById("frogLoaderVersionReleaseBadge").innerHTML = "No version found!"
}),
fetchVersionFromMaven("releases", "phytotelma").then((v) => {
latestPhytotelma = v
document.getElementById("phytotelmaVersionReleaseBadge").innerHTML = v
}).catch((err) => {
document.getElementById("phytotelmaVersionReleaseBadge").innerHTML = "No version found!"
}),
fetchVersionFromMaven("releases", "froglib").then((v) => {
latestFrogLib = v
document.getElementById("froglibVersionReleaseBadge").innerHTML = v
}).catch((err) => {
document.getElementById("froglibVersionReleaseBadge").innerHTML = "No version found!"
}),
fetchVersionFromMaven("snapshots", "frogloader").then((v) => {
latestLoaderSnapshot = v
document.getElementById("frogLoaderVersionSnapshotBadge").innerHTML = v
}),
fetchVersionFromMaven("snapshots", "phytotelma").then((v) => {
latestPhytotelmaSnapshot = v
document.getElementById("phytotelmaVersionSnapshotBadge").innerHTML = v
}),
fetchVersionFromMaven("snapshots", "froglib").then((v) => {
latestFrogLibSnapshot = v
document.getElementById("froglibVersionSnapshotBadge").innerHTML = v
}).catch((err) => {
document.getElementById("froglibVersionSnapshotBadge").innerHTML = "No version found!"
}),
]).then((data) => {
if (latestLoader === undefined ||
latestPhytotelma === undefined ||
latestFrogLib === undefined) {
useSnapshots.value = true
document.getElementById("snapshotCheckbox").setAttribute("disabled", '')
}
fetchVersionFromMaven("releases", "frogloader").then((v) => {
latestLoader = v
document.getElementById("frogLoaderVersionReleaseBadge").innerHTML = v
}).catch((err) => {
document.getElementById("frogLoaderVersionReleaseBadge").innerHTML = "No version found!"
})
fetchVersionFromMaven("releases", "phytotelma").then((v) => {
latestPhytotelma = v
document.getElementById("phytotelmaVersionReleaseBadge").innerHTML = v
}).catch((err) => {
document.getElementById("phytotelmaVersionReleaseBadge").innerHTML = "No version found!"
})
fetchVersionFromMaven("snapshots", "frogloader").then((v) => {
latestLoaderSnapshot = v
document.getElementById("frogLoaderVersionSnapshotBadge").innerHTML = v
})
fetchVersionFromMaven("snapshots", "phytotelma").then((v) => {
latestPhytotelmaSnapshot = v
document.getElementById("phytotelmaVersionSnapshotBadge").innerHTML = v
})
}
@ -201,14 +172,13 @@ outline: false
let java = main.folder("java")
let resources = main.folder("resources")
let classes = java
for (let part of mavenGroupRef.value.split(".")) {
for (let part of mavenGroupRef.value.split(/\\./g)) {
classes = classes.folder(part)
}
classes = classes.folder(modIdRef.value)
const classFileName = modNameRef.value.replaceAll(" ", "")
promises.push(
readAsset("/src/main/java/Main.java").then((data) => {
classes.file(classFileName+"Main.java", data)
classes.file(classFileName+"Main", data)
})
)
promises.push(
@ -246,7 +216,6 @@ outline: false
data = data.replaceAll("$license", licenseRef.value)
data = data.replaceAll("$loader_version", useSnapshots.value ? latestLoaderSnapshot : latestLoader)
data = data.replaceAll("$phytotelma_version", useSnapshots.value ? latestPhytotelmaSnapshot : latestPhytotelma)
data = data.replaceAll("$froglib_version", useSnapshots.value ? latestFrogLibSnapshot : latestFrogLib)
data = data.replaceAll("$game_version", versionSelector.value.value)
return data
})
@ -292,20 +261,18 @@ outline: false
<tr>
<td>Library Versions</td>
<td>
<input type="checkbox" v-model="useSnapshots" id="snapshotCheckbox">Use Snapshots (Beta Versions)</input>
<input type="checkbox" v-model="useSnapshots">Use Snapshots (Beta Versions)</input>
</td>
</tr>
</tbody>
</table>
<div id="missingBox"></div>
<button id="generate" @click="generate" disabled>Download</button>
<button @click="generate">Download</button>
</div>
## Latest Versions
[FrogLoader](/contributing/tools.md#frogloader) <Badge type="tip" id="frogLoaderVersionReleaseBadge">Loading Release...</Badge> <Badge type="warning" id="frogLoaderVersionSnapshotBadge">Loading Snapshot...</Badge>
[FrogLib](/contributing/tools.md#froglib) <Badge type="tip" id="froglibVersionReleaseBadge">Loading Release...</Badge> <Badge type="warning" id="froglibVersionSnapshotBadge">Loading Snapshot...</Badge>
[Phytotelma](/contributing/tools.md#phytotelma) <Badge type="tip" id="phytotelmaVersionReleaseBadge">Loading Release...</Badge> <Badge type="warning" id="phytotelmaVersionSnapshotBadge">Loading Snapshot...</Badge>

View file

@ -1,4 +0,0 @@
---
outline: deep
---

View file

@ -1,4 +0,0 @@
---
outline: deep
---