Add Linkage to CommonCore and implement SpigotLinker used in BauSystem

This commit is contained in:
2025-09-29 10:17:49 +02:00
parent 04d796bbfc
commit ca589bd07c
21 changed files with 297 additions and 178 deletions
+26
View File
@@ -0,0 +1,26 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2024 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
plugins {
steamwar.java
}
dependencies {
compileOnly(libs.classindex)
}
@@ -0,0 +1,152 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2020 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.linkage;
import de.steamwar.linkage.api.Disable;
import de.steamwar.linkage.api.Enable;
import lombok.NonNull;
import lombok.experimental.StandardException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
public abstract class AbstractLinker<T> {
protected final T plugin;
private Map<Class<?>, Object> instances = new HashMap<>();
protected AbstractLinker(@NonNull T plugin) {
this.plugin = plugin;
instances.put(plugin.getClass(), plugin);
}
@StandardException
public static class LinkException extends Exception {
}
public final void link() throws LinkException {
List<Class<?>> classes;
try {
classes = new BufferedReader(new InputStreamReader(plugin.getClass().getResourceAsStream("/META-INF/annotations/de.steamwar.linkage.Linked")))
.lines()
.map(s -> {
try {
return Class.forName(s, false, plugin.getClass().getClassLoader());
} catch (ClassNotFoundException | NoClassDefFoundError e) {
throw new SecurityException(e.getMessage(), e);
}
})
.filter(Objects::nonNull)
.collect(Collectors.toList());
} catch (SecurityException e) {
Throwable cause = e.getCause();
throw new LinkException(cause.getMessage(), cause);
}
try {
classes.forEach(clazz -> {
MinVersion minVersion = clazz.getAnnotation(MinVersion.class);
MaxVersion maxVersion = clazz.getAnnotation(MaxVersion.class);
if (!versionCheck(clazz, minVersion, maxVersion)) return;
PluginCheck[] pluginChecks = clazz.getAnnotationsByType(PluginCheck.class);
for (PluginCheck pluginCheck : pluginChecks) {
if (!pluginCheck(clazz, pluginCheck)) return;
}
Object any;
try {
any = clazz.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
throw new SecurityException(e.getMessage());
}
instances.put(clazz, any);
if (any instanceof Enable) {
((Enable) any).enable();
}
linkObject(any);
});
} catch (SecurityException e) {
Throwable cause = e.getCause();
throw new LinkException(cause.getMessage(), cause);
}
try {
instances.forEach((clazz, o) -> {
for (Field field : clazz.getFields()) {
if (field.getAnnotation(LinkedInstance.class) != null) {
System.out.println("Setting " + field.getName() + " to " + instances.get(field.getType()));
try {
field.set(o, instances.get(field.getType()));
} catch (IllegalAccessException e) {
throw new SecurityException(e);
}
}
}
});
} catch (SecurityException e) {
Throwable cause = e.getCause();
throw new LinkException(cause.getMessage(), cause);
}
}
public final void unlink() {
instances.forEach((aClass, any) -> {
unlinkObject(any);
if (any instanceof Disable) {
((Disable) any).disable();
}
});
}
public final void addLinkableInstance(@NonNull Object instance) {
instances.put(instance.getClass(), instance);
}
/**
* @return {@code true} if the clazz passes the checks {@code false} otherwise
*/
protected boolean versionCheck(@NonNull Class<?> clazz, MinVersion minVersion, MaxVersion maxVersion) {
return true;
}
/**
* @return {@code true} if the clazz passes the checks {@code false} otherwise
*/
protected boolean pluginCheck(@NonNull Class<?> clazz, PluginCheck pluginCheck) {
return true;
}
/**
* There is no need in calling {@link Enable#enable()} by this method.
*/
protected abstract void linkObject(Object any);
/**
* There is no need in calling {@link Disable#disable()} ()} by this method.
*/
protected abstract void unlinkObject(Object any);
}
@@ -0,0 +1,33 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2022 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.linkage;
import org.atteo.classindex.IndexAnnotated;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@IndexAnnotated
@Retention(RetentionPolicy.SOURCE)
@Target({ElementType.TYPE})
public @interface Linked {
}
@@ -0,0 +1,30 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2022 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.linkage;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface LinkedInstance {
}
@@ -0,0 +1,31 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2022 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.linkage;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface MaxVersion {
int value();
}
@@ -0,0 +1,31 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2022 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.linkage;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface MinVersion {
int value();
}
@@ -0,0 +1,41 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2022 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.linkage;
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Repeatable(PluginCheck.PluginChecks.class)
public @interface PluginCheck {
Has has() default Has.THIS;
String value();
enum Has {
THIS,
NOT
}
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@interface PluginChecks {
@SuppressWarnings("unused") PluginCheck[] value() default {};
}
}
@@ -0,0 +1,24 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2024 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.linkage.api;
public interface Disable {
void disable();
}
@@ -0,0 +1,24 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2024 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.linkage.api;
public interface Enable {
void enable();
}
+1
View File
@@ -25,4 +25,5 @@ dependencies {
api(project(":CommonCore:SQL"))
api(project(":CommonCore:Network"))
api(project(":CommonCore:Data"))
api(project(":CommonCore:Linkage"))
}