parent
					
						
							
								6c1e0da6b6
							
						
					
				
			
			
				commit
				
					
						d54508cc81
					
				
			
		
					 15 changed files with 156 additions and 41 deletions
				
			
		
							
								
								
									
										46
									
								
								README.md
									
										
									
									
									
								
							
							
						
						
									
										46
									
								
								README.md
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,19 +1,39 @@
 | 
			
		|||
# tweaks724
 | 
			
		||||
 | 
			
		||||
Dependencies: ProtocolLib
 | 
			
		||||
Stuff no<sub><sup>t many</sup></sub> other plugins have.
 | 
			
		||||
 | 
			
		||||
### Caveats
 | 
			
		||||
Disable "secure chat"
 | 
			
		||||
Dependencies:
 | 
			
		||||
- [ProtocolLib](https://www.spigotmc.org/resources/protocollib.1997/) (optional, but you lose a lot)
 | 
			
		||||
 | 
			
		||||
### Chatrooms
 | 
			
		||||
- `/c` to see info about current chatroom
 | 
			
		||||
- `/c <name>` to join a chatroom
 | 
			
		||||
- `/cm create <name>` to create a chatroom
 | 
			
		||||
- `/cm set* <name>` to change a setting (for owners)
 | 
			
		||||
# Features
 | 
			
		||||
 | 
			
		||||
### Commands
 | 
			
		||||
- `/dkick` - discreet kick. The player will be kicked with a cryptic error message, and those smarter will think it's a plugin bug.[^1] Brilliant!
 | 
			
		||||
- `/ping` - checks ping. Ping is checked using a more accurate[^2] method
 | 
			
		||||
Those with <sup>P</sup> need ProtocolLib
 | 
			
		||||
 | 
			
		||||
[^1]: or, better, client bug, if they don't trust their client
 | 
			
		||||
[^2]: not
 | 
			
		||||
### World border <sup><sup><sub>P</sub></sup></sup>
 | 
			
		||||
Hides the world border. It's still there, just invisible.
 | 
			
		||||
 | 
			
		||||
### Server brand <sup><sup><sub>P</sub></sup></sup>
 | 
			
		||||
Modify the F3 brand, optionally include player's ping and server performance
 | 
			
		||||
 | 
			
		||||
### Doors
 | 
			
		||||
Open two doors with one click. Knock on doors.
 | 
			
		||||
 | 
			
		||||
### MOTD <sup><sup><sub>P</sub></sup></sup>
 | 
			
		||||
Random MOTD for every ping
 | 
			
		||||
 | 
			
		||||
### Chat rooms
 | 
			
		||||
Chat rooms players can freely create and join. Alerts like death and join messages are only within the player's chat room.
 | 
			
		||||
 | 
			
		||||
### Compass
 | 
			
		||||
Holding a compass shows a bar with 4 directions and stuff like beds, lodestones, death pos (TODO) etc.
 | 
			
		||||
 | 
			
		||||
### Pomodoro
 | 
			
		||||
Self-discipline with a pomodoro timer that's actually forced
 | 
			
		||||
 | 
			
		||||
### Updater
 | 
			
		||||
Updates ALL[^1] your plugins
 | 
			
		||||
 | 
			
		||||
[^1]: Those on SpigotMC and that release updates there
 | 
			
		||||
 | 
			
		||||
### Hardcore <sup><sup><sub>P</sub></sup></sup>
 | 
			
		||||
Hardcore hearts by chance
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										26
									
								
								src/main/java/eu/m724/tweaks/Language.java
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								src/main/java/eu/m724/tweaks/Language.java
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,26 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (C) 2024  Minecon724
 | 
			
		||||
 * Tweaks724 is licensed under the GNU General Public License. See the LICENSE.md file
 | 
			
		||||
 * in the project root for the full license text.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package eu.m724.tweaks;
 | 
			
		||||
 | 
			
		||||
import java.util.Locale;
 | 
			
		||||
import java.util.ResourceBundle;
 | 
			
		||||
 | 
			
		||||
public class Language {
 | 
			
		||||
    private final ResourceBundle resourceBundle;
 | 
			
		||||
 | 
			
		||||
    private static Language INSTANCE = null;
 | 
			
		||||
 | 
			
		||||
    Language(Locale locale) {
 | 
			
		||||
        this.resourceBundle = ResourceBundle.getBundle("strings", locale);
 | 
			
		||||
 | 
			
		||||
        INSTANCE = this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static String getString(String key) {
 | 
			
		||||
        return INSTANCE.resourceBundle.getString(key);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -55,7 +55,7 @@ public record TweaksConfig(
 | 
			
		|||
 | 
			
		||||
        boolean isProtocolLib = plugin.getServer().getPluginManager().getPlugin("ProtocolLib") != null;
 | 
			
		||||
 | 
			
		||||
        int configVersion = config.getInt("magic number dont modify this", 0);
 | 
			
		||||
        int configVersion = config.getInt("magic number don't modify this", 0);
 | 
			
		||||
        RuntimeException exception = new RuntimeException("Config version is %d, expected %d".formatted(configVersion, CONFIG_VERSION));
 | 
			
		||||
        if (configVersion == 0) {
 | 
			
		||||
            throw exception;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,12 +21,16 @@ import eu.m724.tweaks.worldborder.WorldBorderManager;
 | 
			
		|||
import org.bukkit.plugin.java.JavaPlugin;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.util.Locale;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
 | 
			
		||||
public class TweaksPlugin extends JavaPlugin {
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onEnable() {
 | 
			
		||||
        long start = System.nanoTime();
 | 
			
		||||
 | 
			
		||||
        TweaksConfig config = TweaksConfig.load(this);
 | 
			
		||||
        new Language(Locale.US); // TODO
 | 
			
		||||
 | 
			
		||||
        if (config.chatEnabled()) {
 | 
			
		||||
            ChatManager chatManager = new ChatManager(this);
 | 
			
		||||
| 
						 | 
				
			
			@ -81,6 +85,11 @@ public class TweaksPlugin extends JavaPlugin {
 | 
			
		|||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        new HardcoreManager().init(this);
 | 
			
		||||
        if (config.hardcoreEnabled()) {
 | 
			
		||||
            new HardcoreManager().init(this);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        getLogger().info("Took %.3f milliseconds".formatted((System.nanoTime() - start) / 1000000.0));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -78,7 +78,7 @@ public class CompassListener implements Listener {
 | 
			
		|||
        if (player.getBedSpawnLocation() != null) {
 | 
			
		||||
            if (player.getBedSpawnLocation().getWorld().equals(player.getWorld())) {
 | 
			
		||||
                double respawnYaw = calculateYaw(player.getLocation(), player.getBedSpawnLocation());
 | 
			
		||||
                System.out.println(respawnYaw);
 | 
			
		||||
                //System.out.println(respawnYaw);
 | 
			
		||||
                currentPoints.put((int) respawnYaw, ChatColor.GREEN + "r");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										20
									
								
								src/main/java/eu/m724/tweaks/full/FullListener.java
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/main/java/eu/m724/tweaks/full/FullListener.java
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,20 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (C) 2024  Minecon724
 | 
			
		||||
 * Tweaks724 is licensed under the GNU General Public License. See the LICENSE.md file
 | 
			
		||||
 * in the project root for the full license text.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package eu.m724.tweaks.full;
 | 
			
		||||
 | 
			
		||||
import org.bukkit.event.EventHandler;
 | 
			
		||||
import org.bukkit.event.Listener;
 | 
			
		||||
import org.bukkit.event.player.PlayerLoginEvent;
 | 
			
		||||
 | 
			
		||||
public class FullListener implements Listener {
 | 
			
		||||
    @EventHandler
 | 
			
		||||
    public void onPlayerLogin(PlayerLoginEvent event) {
 | 
			
		||||
        if (event.getResult() == PlayerLoginEvent.Result.KICK_FULL && event.getPlayer().hasPermission("tweaks724.full.exempt")) {
 | 
			
		||||
            event.allow();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -42,9 +42,12 @@ public class MotdManager {
 | 
			
		|||
        String motdSetName = TweaksConfig.getConfig().motdSet();
 | 
			
		||||
        File motdSetsFile = new File(plugin.getDataFolder() + "/motd sets/" + motdSetName + ".txt");
 | 
			
		||||
 | 
			
		||||
        // if the directory didn't exist create example motd sets
 | 
			
		||||
        if (motdSetsFile.getParentFile().mkdirs()) {
 | 
			
		||||
            plugin.saveResource("motd sets/" + motdSetName + ".txt", true);
 | 
			
		||||
        motdSetsFile.getParentFile().mkdirs();
 | 
			
		||||
        // if this is a builtin set
 | 
			
		||||
        plugin.saveResource("motd sets/" + motdSetName + ".txt", false);
 | 
			
		||||
 | 
			
		||||
        if (!motdSetsFile.exists()) {
 | 
			
		||||
            throw new RuntimeException("MOTD set \"%s\" doesn't exist (%s)".formatted(motdSetName, motdSetsFile.getPath()));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        String fileContent = Files.readString(motdSetsFile.toPath());
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -36,7 +36,7 @@ public class PluginScanner {
 | 
			
		|||
        Set<SpigotResource> spigotResources = new HashSet<>();
 | 
			
		||||
 | 
			
		||||
        for (Plugin plugin : plugins) {
 | 
			
		||||
            System.out.println("Found "  + plugin.getName());
 | 
			
		||||
           // System.out.println("Found "  + plugin.getName());
 | 
			
		||||
            String pluginName = plugin.getName();
 | 
			
		||||
 | 
			
		||||
            if (!configuration.isSet(pluginName)) {
 | 
			
		||||
| 
						 | 
				
			
			@ -45,9 +45,9 @@ public class PluginScanner {
 | 
			
		|||
            }
 | 
			
		||||
 | 
			
		||||
            int pluginId = configuration.getInt(pluginName);
 | 
			
		||||
            if (pluginId != -1) {
 | 
			
		||||
            if (pluginId > 0) {
 | 
			
		||||
                spigotResources.add(
 | 
			
		||||
                        new SpigotResource(plugin, pluginId)
 | 
			
		||||
                        new SpigotResource(plugin, pluginId, pluginName)
 | 
			
		||||
                );
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,6 +6,7 @@
 | 
			
		|||
 | 
			
		||||
package eu.m724.tweaks.updater;
 | 
			
		||||
 | 
			
		||||
import eu.m724.tweaks.Language;
 | 
			
		||||
import eu.m724.tweaks.updater.cache.VersionedResource;
 | 
			
		||||
import org.bukkit.plugin.Plugin;
 | 
			
		||||
import org.bukkit.scheduler.BukkitRunnable;
 | 
			
		||||
| 
						 | 
				
			
			@ -13,6 +14,8 @@ import org.bukkit.scheduler.BukkitRunnable;
 | 
			
		|||
import java.io.File;
 | 
			
		||||
import java.io.FileOutputStream;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
import java.util.concurrent.CompletionException;
 | 
			
		||||
import java.util.logging.Logger;
 | 
			
		||||
| 
						 | 
				
			
			@ -23,6 +26,8 @@ public class UpdateChecker extends BukkitRunnable {
 | 
			
		|||
    private final Logger logger;
 | 
			
		||||
    private final File cacheFile;
 | 
			
		||||
 | 
			
		||||
    private final Set<VersionedResource> availableUpdates = new HashSet<>();
 | 
			
		||||
 | 
			
		||||
    UpdateChecker(Plugin plugin, Set<VersionedResource> resources) {
 | 
			
		||||
        this.logger = Logger.getLogger(plugin.getLogger().getName() + "." + getClass().getSimpleName());
 | 
			
		||||
        this.resources = resources; // TODO make a copy?
 | 
			
		||||
| 
						 | 
				
			
			@ -30,9 +35,12 @@ public class UpdateChecker extends BukkitRunnable {
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    private void checkAll() {
 | 
			
		||||
        logger.info("Checking for updates");
 | 
			
		||||
        //logger.info("Checking for updates");
 | 
			
		||||
        availableUpdates.clear();
 | 
			
		||||
 | 
			
		||||
        for (VersionedResource versionedResource : Set.copyOf(resources)) {
 | 
			
		||||
            logger.info(versionedResource.resource().resourceId() + " " + versionedResource.resource().plugin().getName());
 | 
			
		||||
            String pluginName = versionedResource.resource().plugin().getName();
 | 
			
		||||
            //logger.info(versionedResource.resource().resourceId() + " " + versionedResource.resource().plugin().getName());
 | 
			
		||||
            int page = versionedResource.running() != null ? versionedResource.running().page() : 1;
 | 
			
		||||
 | 
			
		||||
            try {
 | 
			
		||||
| 
						 | 
				
			
			@ -40,29 +48,46 @@ public class UpdateChecker extends BukkitRunnable {
 | 
			
		|||
                if (!versionedResource.equals(newResource)) {
 | 
			
		||||
                    resources.remove(versionedResource);
 | 
			
		||||
                    if (newResource.running() == null) {
 | 
			
		||||
                        logger.info("Unable to find installed version of %s".formatted(pluginName));
 | 
			
		||||
                        if (versionedResource.running() != null) {
 | 
			
		||||
                            logger.info("Did you downgrade %s? If so, clear cache");
 | 
			
		||||
                            newResource = null;
 | 
			
		||||
                            logger.info("Did you downgrade %s? If so, clear cache".formatted(pluginName));
 | 
			
		||||
                        }
 | 
			
		||||
                    } else {
 | 
			
		||||
                        if (!newResource.running().equals(newResource.latest())) {
 | 
			
		||||
                            availableUpdates.add(newResource);
 | 
			
		||||
                            //logger.info("Update available for %s. %d -> %d".formatted(pluginName, newResource.running().updateId(), newResource.latest().updateId()));
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    resources.remove(versionedResource);
 | 
			
		||||
                    resources.add(newResource);
 | 
			
		||||
                    // TODO notify and all
 | 
			
		||||
                }
 | 
			
		||||
            } catch (CompletionException e) {
 | 
			
		||||
                logger.severe("Unable to refresh %s: %s".formatted(versionedResource.resource().plugin().getName(), e.getMessage()));
 | 
			
		||||
                logger.severe("Unable to refresh %s: %s".formatted(pluginName, e.getMessage()));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void alert() {
 | 
			
		||||
        int n = availableUpdates.size();
 | 
			
		||||
        if (n == 0) return;
 | 
			
		||||
        logger.info(Language.getString("updateAvailableNotice"));
 | 
			
		||||
 | 
			
		||||
        availableUpdates.stream()
 | 
			
		||||
                .map(u -> "- %s (%s -> %s)".formatted(u.resource().name(), u.running().label(), u.latest().label()))
 | 
			
		||||
                .forEach(logger::info);
 | 
			
		||||
 | 
			
		||||
        // TODO notify player
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void run() {
 | 
			
		||||
        checkAll();
 | 
			
		||||
 | 
			
		||||
        try (FileOutputStream outputStream = new FileOutputStream(cacheFile)) {
 | 
			
		||||
            VersionCheckCache.writeAll(outputStream, resources.stream().map(VersionedResource::running).collect(Collectors.toSet()));
 | 
			
		||||
            VersionCheckCache.writeAll(outputStream, resources.stream().map(VersionedResource::running).filter(Objects::nonNull).collect(Collectors.toSet()));
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
            throw new RuntimeException(e);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        alert();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -29,7 +29,7 @@ public class VersionCheckCache {
 | 
			
		|||
        while (inputStream.available() > 0) {
 | 
			
		||||
            int read = inputStream.read(buffer);
 | 
			
		||||
            if (read < 8) break; // end of file
 | 
			
		||||
            if (++i > 10000) throw new RuntimeException("File is too large");
 | 
			
		||||
            if (++i > 10000) throw new RuntimeException("Cache file is too large");
 | 
			
		||||
 | 
			
		||||
            ResourceVersion resourceVersion = getResourceVersion(buffer);
 | 
			
		||||
            versions.add(resourceVersion);
 | 
			
		||||
| 
						 | 
				
			
			@ -43,7 +43,7 @@ public class VersionCheckCache {
 | 
			
		|||
        int page = ((bytes[3] & 0xFF) << 8) | (bytes[4] & 0xFF);
 | 
			
		||||
        int versionId = ((bytes[5] & 0xFF) << 16) | ((bytes[6] & 0xFF) << 8) | (bytes[7] & 0xFF);
 | 
			
		||||
 | 
			
		||||
        return new ResourceVersion(resourceId, page, versionId);
 | 
			
		||||
        return new ResourceVersion(resourceId, page, versionId, null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static void writeResourceVersion(ResourceVersion resourceVersion, OutputStream outputStream) throws IOException {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -41,7 +41,7 @@ public class VersionFinder extends CompletableFuture<VersionedResource> {
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    private void start() {
 | 
			
		||||
        System.out.printf("STarting for %d %s\n", resource.resourceId(), resource.plugin().getName());
 | 
			
		||||
        //System.out.printf("STarting for %d %s\n", resource.resourceId(), resource.plugin().getName());
 | 
			
		||||
        try (ExecutorService executor = Executors.newSingleThreadExecutor()) {
 | 
			
		||||
            executor.execute(() -> {
 | 
			
		||||
                try {
 | 
			
		||||
| 
						 | 
				
			
			@ -50,7 +50,7 @@ public class VersionFinder extends CompletableFuture<VersionedResource> {
 | 
			
		|||
 | 
			
		||||
                    int page;
 | 
			
		||||
                    for (page = fromPage; page < 1000; page++) {
 | 
			
		||||
                        System.out.println("Page " + page);
 | 
			
		||||
                        //System.out.println("Page " + page);
 | 
			
		||||
                        String url = "https://api.spigotmc.org/simple/0.2/index.php?action=getResourceUpdates&page=%d&id=%d".formatted(page, resource.resourceId());
 | 
			
		||||
 | 
			
		||||
                        HttpRequest request;
 | 
			
		||||
| 
						 | 
				
			
			@ -78,22 +78,24 @@ public class VersionFinder extends CompletableFuture<VersionedResource> {
 | 
			
		|||
                                    runningVersion = new ResourceVersion(
 | 
			
		||||
                                            resource.resourceId(),
 | 
			
		||||
                                            page,
 | 
			
		||||
                                            versionJson.get("id").getAsInt()
 | 
			
		||||
                                            versionJson.get("id").getAsInt(),
 | 
			
		||||
                                            versionJson.get("resource_version").getAsString()
 | 
			
		||||
                                    );
 | 
			
		||||
                                }
 | 
			
		||||
                                latestVersion = new ResourceVersion(
 | 
			
		||||
                                        resource.resourceId(),
 | 
			
		||||
                                        page,
 | 
			
		||||
                                        versionJson.get("id").getAsInt()
 | 
			
		||||
                                        versionJson.get("id").getAsInt(),
 | 
			
		||||
                                        versionJson.get("resource_version").getAsString()
 | 
			
		||||
                                );
 | 
			
		||||
                                System.out.printf("%d %d %s\n", page, versionJson.get("id").getAsInt(), versionJson.get("resource_version").getAsString());
 | 
			
		||||
                                //System.out.printf("%d %d %s\n", page, versionJson.get("id").getAsInt(), versionJson.get("resource_version").getAsString());
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            if (jsonArray.size() < 10) break;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
                    System.out.println("Done");
 | 
			
		||||
                    //System.out.println("Done");
 | 
			
		||||
 | 
			
		||||
                    if (page > 999) {
 | 
			
		||||
                        throw new Exception("Too many pages");
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,5 +9,6 @@ package eu.m724.tweaks.updater.cache;
 | 
			
		|||
public record ResourceVersion(
 | 
			
		||||
        int resourceId,
 | 
			
		||||
        int page,
 | 
			
		||||
        int updateId
 | 
			
		||||
        int updateId,
 | 
			
		||||
        String label
 | 
			
		||||
) { }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,6 +10,7 @@ import org.bukkit.plugin.Plugin;
 | 
			
		|||
 | 
			
		||||
public record SpigotResource(
 | 
			
		||||
        Plugin plugin,
 | 
			
		||||
        int resourceId
 | 
			
		||||
        int resourceId,
 | 
			
		||||
        String name
 | 
			
		||||
) {
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,3 +1,4 @@
 | 
			
		|||
# Here go installed plugins and their SpigotMC resource IDs
 | 
			
		||||
# To ignore a plugin, set it to -1
 | 
			
		||||
# To ignore a plugin, set it to a negative number, like -1
 | 
			
		||||
# Pro tip: Prefix an ID with a minus to disable it without losing the ID
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										7
									
								
								src/main/resources/strings.properties
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								src/main/resources/strings.properties
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,7 @@
 | 
			
		|||
#
 | 
			
		||||
# Copyright (C) 2024  Minecon724
 | 
			
		||||
# Tweaks724 is licensed under the GNU General Public License. See the LICENSE.md file
 | 
			
		||||
# in the project root for the full license text.
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
updateAvailableNotice = Available updates (%d):
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue