generated from natanfudge/fabric-example-mod-kotlin
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
280 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,52 @@ | ||
# Fabric Example Mod - Kotlin | ||
![Gradle build](https://github.com/natanfudge/fabric-example-mod-kotlin/workflows/Gradle%20build/badge.svg) | ||
# Git Mod - A Fabric Mod written in Kotlin | ||
|
||
A server-side git client usable within minecraft chat! | ||
|
||
![example](imgs/example.png) | ||
|
||
To use, navigate to the config folder and locate the `gitmod.json` configuration file. Here, you can define a gitPath (automatically the `datapacks` folder) and a dictionary of operators (name: UUID) for people who are allowed to utilize the git system. | ||
|
||
Then, you can type `/gitconfig reload` to reload the config. | ||
|
||
Now you can type `/git` and any sort of git command and it *should* just work! | ||
Even aliases! | ||
|
||
## Setup | ||
|
||
0. Create a new mod repository by pressing the "Use this template" button and clone the created repository. | ||
0. Make sure you have Git installed are you system and available through your $PATH. If you are on Windows, it's very likely this mod will fail :(. | ||
|
||
1. Install this Mod along side fabric-language-kotlin | ||
|
||
2. Run the server / client to create an empty configuration file `config/gitmod.json` | ||
|
||
3. Edit the config to specify your git repo and the operator's UUID you would like to adjust | ||
|
||
{ | ||
"gitPath": "path to git repo (defaults to datapacks folder)", | ||
"operators": { | ||
"minecraft name": "minecraft UUID" | ||
} | ||
} | ||
|
||
4. ??? | ||
|
||
?. Success? | ||
|
||
|
||
## Details | ||
|
||
At the moment, this is an incredibly cursed mod. Essentially, it takes the arguments of the `/git` cmd and passes it a shell process to run it in a coroutine. If a command is currently running (like a `git pull`), then no other invocations are allowed. This design is extremely restricted to avoid any weird bugs that might come up. | ||
|
||
Also, this mod will heavily rely on your personal git installation since it leverages your shell. In the future, the plan is to develop a client `/git` cmd and a `/gitraw` cmd where `/git` interfaces with the JGit library and `/gitraw` works thru the shell process. For now, we have jank :D. | ||
|
||
Do note that when working with services like `github`, you'll have to work with some sort of authentication to get your `git` to operate with `github` w/o you inputting a password into minecraft (since that will be blocked). This will involve some sort of ssh key or something, so do be aware. I suggest you gave the `git` installation on the server some sort of special email and username to differentiate from normal commits to your repo! | ||
|
||
## Why? | ||
|
||
1. Import build.gradle file with IntelliJ IDEA | ||
This mod is geared towards datapackers. When working on a server, it is not always possible to have an SFTP connection to access and work with the files. This means you might have to edit the files through a HTTPS panel which can be incredibly frustrating. SFTP also has a lue of issue and is not always reliable especially when trying to collaborate with others (like datapack jams). Since `git` is a popular tool and already used in the space, a tool like this can be incredibly helpful and potent. | ||
|
||
2. Edit build.gradle and mod.json to suit your needs. | ||
* The "mixins" object can be removed from mod.json if you do not need to use mixins. | ||
* Please replace all occurences of "modid" with your own mod ID - sometimes, a different string may also suffice. | ||
3. Run! | ||
For example, when working on a datapack ran server, you can have a bunch of experiemental changes applied on a branch and then switch back to your main branch to avoid pollution. It's also extremely viable to have your entire local setup work seemlessly with the server since you can just spam `git commits` as a way of timestamping your changes and pushing to your server. | ||
|
||
## License | ||
|
||
This template is available under the CC0 license. Feel free to learn from it and incorporate it in your own projects. | ||
This project is licensed under the MIT licenses. Any exceptions for this license are detailed in licensing in specific files. |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,229 @@ | ||
/*BEGIN_COPYRIGHT_BLOCK | ||
* | ||
* Copyright (c) 2001-2010, JavaPLT group at Rice University (drjava@rice.edu) | ||
* All rights reserved. | ||
* | ||
* Redistribution and use in source and binary forms, with or without | ||
* modification, are permitted provided that the following conditions are met: | ||
* * Redistributions of source code must retain the above copyright | ||
* notice, this list of conditions and the following disclaimer. | ||
* * Redistributions in binary form must reproduce the above copyright | ||
* notice, this list of conditions and the following disclaimer in the | ||
* documentation and/or other materials provided with the distribution. | ||
* * Neither the names of DrJava, the JavaPLT group, Rice University, nor the | ||
* names of its contributors may be used to endorse or promote products | ||
* derived from this software without specific prior written permission. | ||
* | ||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR | ||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
* | ||
* This software is Open Source Initiative approved Open Source Software. | ||
* Open Source Initative Approved is a trademark of the Open Source Initiative. | ||
* | ||
* This file is part of DrJava. Download the current version of this project | ||
* from http://www.drjava.org/ or http://sourceforge.net/projects/drjava/ | ||
* | ||
* END_COPYRIGHT_BLOCK*/ | ||
|
||
package net.rx.modules; | ||
|
||
import java.util.List; | ||
import java.util.LinkedList; | ||
|
||
/** | ||
* Utility class which can tokenize a String into a list of String arguments, | ||
* with behavior similar to parsing command line arguments to a program. | ||
* Quoted Strings are treated as single arguments, and escaped characters | ||
* are translated so that the tokenized arguments have the same meaning. | ||
* Since all methods are static, the class is declared abstract to prevent | ||
* instantiation. | ||
* @version $Id$ | ||
*/ | ||
public abstract class ArgumentTokenizer { | ||
private static final int NO_TOKEN_STATE = 0; | ||
private static final int NORMAL_TOKEN_STATE = 1; | ||
private static final int SINGLE_QUOTE_STATE = 2; | ||
private static final int DOUBLE_QUOTE_STATE = 3; | ||
|
||
/** Tokenizes the given String into String tokens | ||
* @param arguments A String containing one or more command-line style arguments to be tokenized. | ||
* @return A list of parsed and properly escaped arguments. | ||
*/ | ||
public static List<String> tokenize(String arguments) { | ||
return tokenize(arguments, false); | ||
} | ||
|
||
/** Tokenizes the given String into String tokens. | ||
* @param arguments A String containing one or more command-line style arguments to be tokenized. | ||
* @param stringify whether or not to include escape special characters | ||
* @return A list of parsed and properly escaped arguments. | ||
*/ | ||
public static List<String> tokenize(String arguments, boolean stringify) { | ||
|
||
LinkedList<String> argList = new LinkedList<String>(); | ||
StringBuilder currArg = new StringBuilder(); | ||
boolean escaped = false; | ||
int state = NO_TOKEN_STATE; // start in the NO_TOKEN_STATE | ||
int len = arguments.length(); | ||
|
||
// Loop over each character in the string | ||
for (int i = 0; i < len; i++) { | ||
char c = arguments.charAt(i); | ||
if (escaped) { | ||
// Escaped state: just append the next character to the current arg. | ||
escaped = false; | ||
currArg.append(c); | ||
} | ||
else { | ||
switch(state) { | ||
case SINGLE_QUOTE_STATE: | ||
if (c == '\'') { | ||
// Seen the close quote; continue this arg until whitespace is seen | ||
state = NORMAL_TOKEN_STATE; | ||
} | ||
else { | ||
currArg.append(c); | ||
} | ||
break; | ||
case DOUBLE_QUOTE_STATE: | ||
if (c == '"') { | ||
// Seen the close quote; continue this arg until whitespace is seen | ||
state = NORMAL_TOKEN_STATE; | ||
} | ||
else if (c == '\\') { | ||
// Look ahead, and only escape quotes or backslashes | ||
i++; | ||
char next = arguments.charAt(i); | ||
if (next == '"' || next == '\\') { | ||
currArg.append(next); | ||
} | ||
else { | ||
currArg.append(c); | ||
currArg.append(next); | ||
} | ||
} | ||
else { | ||
currArg.append(c); | ||
} | ||
break; | ||
// case NORMAL_TOKEN_STATE: | ||
// if (Character.isWhitespace(c)) { | ||
// // Whitespace ends the token; start a new one | ||
// argList.add(currArg.toString()); | ||
// currArg = new StringBuffer(); | ||
// state = NO_TOKEN_STATE; | ||
// } | ||
// else if (c == '\\') { | ||
// // Backslash in a normal token: escape the next character | ||
// escaped = true; | ||
// } | ||
// else if (c == '\'') { | ||
// state = SINGLE_QUOTE_STATE; | ||
// } | ||
// else if (c == '"') { | ||
// state = DOUBLE_QUOTE_STATE; | ||
// } | ||
// else { | ||
// currArg.append(c); | ||
// } | ||
// break; | ||
case NO_TOKEN_STATE: | ||
case NORMAL_TOKEN_STATE: | ||
switch(c) { | ||
case '\\': | ||
escaped = true; | ||
state = NORMAL_TOKEN_STATE; | ||
break; | ||
case '\'': | ||
state = SINGLE_QUOTE_STATE; | ||
break; | ||
case '"': | ||
state = DOUBLE_QUOTE_STATE; | ||
break; | ||
default: | ||
if (!Character.isWhitespace(c)) { | ||
currArg.append(c); | ||
state = NORMAL_TOKEN_STATE; | ||
} | ||
else if (state == NORMAL_TOKEN_STATE) { | ||
// Whitespace ends the token; start a new one | ||
argList.add(currArg.toString()); | ||
currArg = new StringBuilder(); | ||
state = NO_TOKEN_STATE; | ||
} | ||
} | ||
break; | ||
default: | ||
throw new IllegalStateException("ArgumentTokenizer state " + state + " is invalid!"); | ||
} | ||
} | ||
} | ||
|
||
// If we're still escaped, put in the backslash | ||
if (escaped) { | ||
currArg.append('\\'); | ||
argList.add(currArg.toString()); | ||
} | ||
// Close the last argument if we haven't yet | ||
else if (state != NO_TOKEN_STATE) { | ||
argList.add(currArg.toString()); | ||
} | ||
// Format each argument if we've been told to stringify them | ||
if (stringify) { | ||
for (int i = 0; i < argList.size(); i++) { | ||
argList.set(i, "\"" + _escapeQuotesAndBackslashes(argList.get(i)) + "\""); | ||
} | ||
} | ||
return argList; | ||
} | ||
|
||
/** Inserts backslashes before any occurrences of a backslash or | ||
* quote in the given string. Also converts any special characters | ||
* appropriately. | ||
*/ | ||
protected static String _escapeQuotesAndBackslashes(String s) { | ||
final StringBuilder buf = new StringBuilder(s); | ||
|
||
// Walk backwards, looking for quotes or backslashes. | ||
// If we see any, insert an extra backslash into the buffer at | ||
// the same index. (By walking backwards, the index into the buffer | ||
// will remain correct as we change the buffer.) | ||
for (int i = s.length()-1; i >= 0; i--) { | ||
char c = s.charAt(i); | ||
if ((c == '\\') || (c == '"')) { | ||
buf.insert(i, '\\'); | ||
} | ||
// Replace any special characters with escaped versions | ||
else if (c == '\n') { | ||
buf.deleteCharAt(i); | ||
buf.insert(i, "\\n"); | ||
} | ||
else if (c == '\t') { | ||
buf.deleteCharAt(i); | ||
buf.insert(i, "\\t"); | ||
} | ||
else if (c == '\r') { | ||
buf.deleteCharAt(i); | ||
buf.insert(i, "\\r"); | ||
} | ||
else if (c == '\b') { | ||
buf.deleteCharAt(i); | ||
buf.insert(i, "\\b"); | ||
} | ||
else if (c == '\f') { | ||
buf.deleteCharAt(i); | ||
buf.insert(i, "\\f"); | ||
} | ||
} | ||
return buf.toString(); | ||
} | ||
} |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters