mirror of
https://github.com/architectury/architectury-api.git
synced 2026-03-28 03:56:59 -05:00
Initial work
This commit is contained in:
16
.gitignore
vendored
Normal file
16
.gitignore
vendored
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
build/
|
||||||
|
*.ipr
|
||||||
|
run/
|
||||||
|
*.iws
|
||||||
|
out/
|
||||||
|
*.iml
|
||||||
|
.gradle/
|
||||||
|
output/
|
||||||
|
bin/
|
||||||
|
libs/
|
||||||
|
|
||||||
|
.classpath
|
||||||
|
.project
|
||||||
|
.settings/org.eclipse.core.resources.prefs
|
||||||
|
.idea/
|
||||||
|
classes/
|
||||||
13
HEADER
Normal file
13
HEADER
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
Copyright ${year} ${name}
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
170
LICENSE.md
Normal file
170
LICENSE.md
Normal file
@@ -0,0 +1,170 @@
|
|||||||
|
Apache License
|
||||||
|
==============
|
||||||
|
|
||||||
|
_Version 2.0, January 2004_
|
||||||
|
_<<http://www.apache.org/licenses/>>_
|
||||||
|
|
||||||
|
### Terms and Conditions for use, reproduction, and distribution
|
||||||
|
|
||||||
|
#### 1. Definitions
|
||||||
|
|
||||||
|
“License” shall mean the terms and conditions for use, reproduction, and
|
||||||
|
distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
“Licensor” shall mean the copyright owner or entity authorized by the copyright
|
||||||
|
owner that is granting the License.
|
||||||
|
|
||||||
|
“Legal Entity” shall mean the union of the acting entity and all other entities
|
||||||
|
that control, are controlled by, or are under common control with that entity.
|
||||||
|
For the purposes of this definition, “control” means **(i)** the power, direct or
|
||||||
|
indirect, to cause the direction or management of such entity, whether by
|
||||||
|
contract or otherwise, or **(ii)** ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or **(iii)** beneficial ownership of such entity.
|
||||||
|
|
||||||
|
“You” (or “Your”) shall mean an individual or Legal Entity exercising
|
||||||
|
permissions granted by this License.
|
||||||
|
|
||||||
|
“Source” form shall mean the preferred form for making modifications, including
|
||||||
|
but not limited to software source code, documentation source, and configuration
|
||||||
|
files.
|
||||||
|
|
||||||
|
“Object” form shall mean any form resulting from mechanical transformation or
|
||||||
|
translation of a Source form, including but not limited to compiled object code,
|
||||||
|
generated documentation, and conversions to other media types.
|
||||||
|
|
||||||
|
“Work” shall mean the work of authorship, whether in Source or Object form, made
|
||||||
|
available under the License, as indicated by a copyright notice that is included
|
||||||
|
in or attached to the work (an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
“Derivative Works” shall mean any work, whether in Source or Object form, that
|
||||||
|
is based on (or derived from) the Work and for which the editorial revisions,
|
||||||
|
annotations, elaborations, or other modifications represent, as a whole, an
|
||||||
|
original work of authorship. For the purposes of this License, Derivative Works
|
||||||
|
shall not include works that remain separable from, or merely link (or bind by
|
||||||
|
name) to the interfaces of, the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
“Contribution” shall mean any work of authorship, including the original version
|
||||||
|
of the Work and any modifications or additions to that Work or Derivative Works
|
||||||
|
thereof, that is intentionally submitted to Licensor for inclusion in the Work
|
||||||
|
by the copyright owner or by an individual or Legal Entity authorized to submit
|
||||||
|
on behalf of the copyright owner. For the purposes of this definition,
|
||||||
|
“submitted” means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems, and
|
||||||
|
issue tracking systems that are managed by, or on behalf of, the Licensor for
|
||||||
|
the purpose of discussing and improving the Work, but excluding communication
|
||||||
|
that is conspicuously marked or otherwise designated in writing by the copyright
|
||||||
|
owner as “Not a Contribution.”
|
||||||
|
|
||||||
|
“Contributor” shall mean Licensor and any individual or Legal Entity on behalf
|
||||||
|
of whom a Contribution has been received by Licensor and subsequently
|
||||||
|
incorporated within the Work.
|
||||||
|
|
||||||
|
#### 2. Grant of Copyright License
|
||||||
|
|
||||||
|
Subject to the terms and conditions of this License, each Contributor hereby
|
||||||
|
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
|
||||||
|
irrevocable copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the Work and such
|
||||||
|
Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
#### 3. Grant of Patent License
|
||||||
|
|
||||||
|
Subject to the terms and conditions of this License, each Contributor hereby
|
||||||
|
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
|
||||||
|
irrevocable (except as stated in this section) patent license to make, have
|
||||||
|
made, use, offer to sell, sell, import, and otherwise transfer the Work, where
|
||||||
|
such license applies only to those patent claims licensable by such Contributor
|
||||||
|
that are necessarily infringed by their Contribution(s) alone or by combination
|
||||||
|
of their Contribution(s) with the Work to which such Contribution(s) was
|
||||||
|
submitted. If You institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work or a
|
||||||
|
Contribution incorporated within the Work constitutes direct or contributory
|
||||||
|
patent infringement, then any patent licenses granted to You under this License
|
||||||
|
for that Work shall terminate as of the date such litigation is filed.
|
||||||
|
|
||||||
|
#### 4. Redistribution
|
||||||
|
|
||||||
|
You may reproduce and distribute copies of the Work or Derivative Works thereof
|
||||||
|
in any medium, with or without modifications, and in Source or Object form,
|
||||||
|
provided that You meet the following conditions:
|
||||||
|
|
||||||
|
* **(a)** You must give any other recipients of the Work or Derivative Works a copy of
|
||||||
|
this License; and
|
||||||
|
* **(b)** You must cause any modified files to carry prominent notices stating that You
|
||||||
|
changed the files; and
|
||||||
|
* **(c)** You must retain, in the Source form of any Derivative Works that You distribute,
|
||||||
|
all copyright, patent, trademark, and attribution notices from the Source form
|
||||||
|
of the Work, excluding those notices that do not pertain to any part of the
|
||||||
|
Derivative Works; and
|
||||||
|
* **(d)** If the Work includes a “NOTICE” text file as part of its distribution, then any
|
||||||
|
Derivative Works that You distribute must include a readable copy of the
|
||||||
|
attribution notices contained within such NOTICE file, excluding those notices
|
||||||
|
that do not pertain to any part of the Derivative Works, in at least one of the
|
||||||
|
following places: within a NOTICE text file distributed as part of the
|
||||||
|
Derivative Works; within the Source form or documentation, if provided along
|
||||||
|
with the Derivative Works; or, within a display generated by the Derivative
|
||||||
|
Works, if and wherever such third-party notices normally appear. The contents of
|
||||||
|
the NOTICE file are for informational purposes only and do not modify the
|
||||||
|
License. You may add Your own attribution notices within Derivative Works that
|
||||||
|
You distribute, alongside or as an addendum to the NOTICE text from the Work,
|
||||||
|
provided that such additional attribution notices cannot be construed as
|
||||||
|
modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and may provide
|
||||||
|
additional or different license terms and conditions for use, reproduction, or
|
||||||
|
distribution of Your modifications, or for any such Derivative Works as a whole,
|
||||||
|
provided Your use, reproduction, and distribution of the Work otherwise complies
|
||||||
|
with the conditions stated in this License.
|
||||||
|
|
||||||
|
#### 5. Submission of Contributions
|
||||||
|
|
||||||
|
Unless You explicitly state otherwise, any Contribution intentionally submitted
|
||||||
|
for inclusion in the Work by You to the Licensor shall be under the terms and
|
||||||
|
conditions of this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify the terms of
|
||||||
|
any separate license agreement you may have executed with Licensor regarding
|
||||||
|
such Contributions.
|
||||||
|
|
||||||
|
#### 6. Trademarks
|
||||||
|
|
||||||
|
This License does not grant permission to use the trade names, trademarks,
|
||||||
|
service marks, or product names of the Licensor, except as required for
|
||||||
|
reasonable and customary use in describing the origin of the Work and
|
||||||
|
reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
#### 7. Disclaimer of Warranty
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, Licensor provides the
|
||||||
|
Work (and each Contributor provides its Contributions) on an “AS IS” BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||||
|
including, without limitation, any warranties or conditions of TITLE,
|
||||||
|
NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
|
||||||
|
solely responsible for determining the appropriateness of using or
|
||||||
|
redistributing the Work and assume any risks associated with Your exercise of
|
||||||
|
permissions under this License.
|
||||||
|
|
||||||
|
#### 8. Limitation of Liability
|
||||||
|
|
||||||
|
In no event and under no legal theory, whether in tort (including negligence),
|
||||||
|
contract, or otherwise, unless required by applicable law (such as deliberate
|
||||||
|
and grossly negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special, incidental,
|
||||||
|
or consequential damages of any character arising as a result of this License or
|
||||||
|
out of the use or inability to use the Work (including but not limited to
|
||||||
|
damages for loss of goodwill, work stoppage, computer failure or malfunction, or
|
||||||
|
any and all other commercial damages or losses), even if such Contributor has
|
||||||
|
been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
#### 9. Accepting Warranty or Additional Liability
|
||||||
|
|
||||||
|
While redistributing the Work or Derivative Works thereof, You may choose to
|
||||||
|
offer, and charge a fee for, acceptance of support, warranty, indemnity, or
|
||||||
|
other liability obligations and/or rights consistent with this License. However,
|
||||||
|
in accepting such obligations, You may act only on Your own behalf and on Your
|
||||||
|
sole responsibility, not on behalf of any other Contributor, and only if You
|
||||||
|
agree to indemnify, defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason of your
|
||||||
|
accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
_END OF TERMS AND CONDITIONS_
|
||||||
36
build.gradle
Normal file
36
build.gradle
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
plugins {
|
||||||
|
id "architect-plugin" version "1.0.10"
|
||||||
|
id "org.cadixdev.licenser" version "0.5.0"
|
||||||
|
}
|
||||||
|
|
||||||
|
architect {
|
||||||
|
minecraft = rootProject.minecraft_version
|
||||||
|
}
|
||||||
|
|
||||||
|
allprojects {
|
||||||
|
apply plugin: "java"
|
||||||
|
apply plugin: "architect-plugin"
|
||||||
|
apply plugin: "org.cadixdev.licenser"
|
||||||
|
|
||||||
|
archivesBaseName = rootProject.archives_base_name
|
||||||
|
version = rootProject.mod_version
|
||||||
|
group = rootProject.maven_group
|
||||||
|
|
||||||
|
tasks.withType(JavaCompile) {
|
||||||
|
options.encoding = "UTF-8"
|
||||||
|
}
|
||||||
|
|
||||||
|
license {
|
||||||
|
header = rootProject.file("HEADER")
|
||||||
|
|
||||||
|
ext {
|
||||||
|
name = "shedaniel"
|
||||||
|
year = 2020
|
||||||
|
}
|
||||||
|
|
||||||
|
ignoreFailures = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
task licenseFormatAll
|
||||||
|
subprojects { p -> licenseFormatAll.dependsOn("${p.path}:licenseFormat") }
|
||||||
16
common/build.gradle
Normal file
16
common/build.gradle
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
plugins {
|
||||||
|
id "fabric-loom"
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
minecraft "com.mojang:minecraft:${rootProject.architect.minecraft}"
|
||||||
|
mappings minecraft.officialMojangMappings()
|
||||||
|
// We depend on fabric loader here to use the fabric @Environment annotations
|
||||||
|
// Do NOT use other classes from fabric loader
|
||||||
|
modCompile "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}"
|
||||||
|
implementation "net.jodah:typetools:0.6.2"
|
||||||
|
}
|
||||||
|
|
||||||
|
architect {
|
||||||
|
common()
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 shedaniel
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package me.shedaniel.architectury;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
|
|
||||||
|
@ApiStatus.Internal
|
||||||
|
public class Architectury {
|
||||||
|
private static final String MOD_LOADER;
|
||||||
|
|
||||||
|
public static String getModLoader() {
|
||||||
|
return MOD_LOADER;
|
||||||
|
}
|
||||||
|
|
||||||
|
static {
|
||||||
|
String loader;
|
||||||
|
try {
|
||||||
|
Class.forName("net.fabricmc.loader.FabricLoader");
|
||||||
|
loader = "fabric";
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
loader = "forge";
|
||||||
|
}
|
||||||
|
MOD_LOADER = loader;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 shedaniel
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package me.shedaniel.architectury;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.reflect.FieldUtils;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
|
|
||||||
|
public final class ArchitecturyPopulator {
|
||||||
|
private ArchitecturyPopulator() {}
|
||||||
|
|
||||||
|
public static void populate(Object o) {
|
||||||
|
try {
|
||||||
|
if (o instanceof Class) {
|
||||||
|
Class<?> aClass = (Class<?>) o;
|
||||||
|
for (Field field : aClass.getDeclaredFields()) {
|
||||||
|
if (!field.isAnnotationPresent(Populatable.class)) continue;
|
||||||
|
if (Modifier.isStatic(field.getModifiers())) {
|
||||||
|
FieldUtils.removeFinalModifier(field);
|
||||||
|
field.setAccessible(true);
|
||||||
|
String type = field.getType().toString().replace("$", "");
|
||||||
|
Class<?> newClass = Class.forName(type.substring(0, type.lastIndexOf('.')) + "." + Architectury.getModLoader() + "." + type.substring(type.lastIndexOf('.') + 1));
|
||||||
|
field.set(null, newClass.getConstructor().newInstance());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (Field field : o.getClass().getDeclaredFields()) {
|
||||||
|
if (!field.isAnnotationPresent(Populatable.class)) continue;
|
||||||
|
if (!Modifier.isStatic(field.getModifiers())) {
|
||||||
|
FieldUtils.removeFinalModifier(field);
|
||||||
|
field.setAccessible(true);
|
||||||
|
String type = field.getType().toString().replace("$", "");
|
||||||
|
Class<?> newClass = Class.forName(type.substring(0, type.lastIndexOf('.')) + "." + Architectury.getModLoader() + "." + type.substring(type.lastIndexOf('.') + 1));
|
||||||
|
field.set(o, newClass.getConstructor().newInstance());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Throwable e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 shedaniel
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package me.shedaniel.architectury;
|
||||||
|
|
||||||
|
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 Populatable {
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 shedaniel
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package me.shedaniel.architectury.event;
|
||||||
|
|
||||||
|
public interface Event<T> {
|
||||||
|
T invoker();
|
||||||
|
|
||||||
|
void register(T listener);
|
||||||
|
|
||||||
|
void unregister(T listener);
|
||||||
|
|
||||||
|
boolean isRegistered(T listener);
|
||||||
|
|
||||||
|
void clearListeners();
|
||||||
|
}
|
||||||
@@ -0,0 +1,150 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 shedaniel
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package me.shedaniel.architectury.event;
|
||||||
|
|
||||||
|
import com.google.common.reflect.AbstractInvocationHandler;
|
||||||
|
import me.shedaniel.architectury.ArchitecturyPopulator;
|
||||||
|
import me.shedaniel.architectury.Populatable;
|
||||||
|
import me.shedaniel.architectury.platform.Platform;
|
||||||
|
import net.fabricmc.api.EnvType;
|
||||||
|
import net.fabricmc.api.Environment;
|
||||||
|
import net.jodah.typetools.TypeResolver;
|
||||||
|
import net.minecraft.world.InteractionResult;
|
||||||
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
|
|
||||||
|
import java.lang.reflect.Array;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.lang.reflect.Proxy;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
public final class EventFactory {
|
||||||
|
private EventFactory() {}
|
||||||
|
|
||||||
|
@Populatable
|
||||||
|
private static final Impl IMPL = null;
|
||||||
|
|
||||||
|
public static <T> Event<T> create(Function<T[], T> function) {
|
||||||
|
Class<?>[] arguments = TypeResolver.resolveRawArguments(Function.class, function.getClass());
|
||||||
|
return new EventImpl<>(arguments[1], function);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("UnstableApiUsage")
|
||||||
|
public static <T> Event<T> createLoop(Class<T> clazz) {
|
||||||
|
return create(ts -> (T) Proxy.newProxyInstance(EventFactory.class.getClassLoader(), new Class[]{clazz}, new AbstractInvocationHandler() {
|
||||||
|
@Override
|
||||||
|
protected Object handleInvocation(Object proxy, Method method, Object[] args) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("UnstableApiUsage")
|
||||||
|
public static <T> Event<T> createInteractionResult(Class<T> clazz) {
|
||||||
|
return create(ts -> (T) Proxy.newProxyInstance(EventFactory.class.getClassLoader(), new Class[]{clazz}, new AbstractInvocationHandler() {
|
||||||
|
@Override
|
||||||
|
protected Object handleInvocation(Object proxy, Method method, Object[] args) throws Throwable {
|
||||||
|
T[] listeners = (T[]) args;
|
||||||
|
for (T listener : listeners) {
|
||||||
|
InteractionResult result = (InteractionResult) method.invoke(listener, args);
|
||||||
|
if (result != InteractionResult.PASS) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return InteractionResult.PASS;
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class EventImpl<T> implements Event<T> {
|
||||||
|
private final Function<T[], T> function;
|
||||||
|
private T invoker = null;
|
||||||
|
private T[] listeners;
|
||||||
|
private Class<?> clazz;
|
||||||
|
|
||||||
|
public EventImpl(Class<?> clazz, Function<T[], T> function) {
|
||||||
|
this.clazz = Objects.requireNonNull(clazz);
|
||||||
|
this.function = function;
|
||||||
|
this.listeners = emptyArray();
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
private T[] emptyArray() {
|
||||||
|
try {
|
||||||
|
return (T[]) Array.newInstance(clazz, 0);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T invoker() {
|
||||||
|
return invoker;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void register(T listener) {
|
||||||
|
listeners = ArrayUtils.add(listeners, listener);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void unregister(T listener) {
|
||||||
|
listeners = ArrayUtils.removeElement(listeners, listener);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isRegistered(T listener) {
|
||||||
|
return ArrayUtils.contains(listeners, listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearListeners() {
|
||||||
|
listeners = emptyArray();
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update() {
|
||||||
|
if (listeners.length == 1) {
|
||||||
|
invoker = listeners[0];
|
||||||
|
} else {
|
||||||
|
invoker = function.apply(listeners);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface Impl {
|
||||||
|
@Environment(EnvType.CLIENT)
|
||||||
|
void registerClient();
|
||||||
|
|
||||||
|
void registerCommon();
|
||||||
|
|
||||||
|
@Environment(EnvType.SERVER)
|
||||||
|
void registerServer();
|
||||||
|
}
|
||||||
|
|
||||||
|
static {
|
||||||
|
ArchitecturyPopulator.populate(EventFactory.class);
|
||||||
|
if (Platform.getEnv() == EnvType.CLIENT)
|
||||||
|
IMPL.registerClient();
|
||||||
|
IMPL.registerCommon();
|
||||||
|
if (Platform.getEnv() == EnvType.SERVER)
|
||||||
|
IMPL.registerServer();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 shedaniel
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package me.shedaniel.architectury.event.events;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
|
import me.shedaniel.architectury.event.Event;
|
||||||
|
import me.shedaniel.architectury.event.EventFactory;
|
||||||
|
|
||||||
|
public interface GuiEvent {
|
||||||
|
Event<RenderHud> RENDER_HUD = EventFactory.createLoop(RenderHud.class);
|
||||||
|
|
||||||
|
interface RenderHud {
|
||||||
|
void renderHud(PoseStack matrices, float tickDelta);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 shedaniel
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package me.shedaniel.architectury.event.events;
|
||||||
|
|
||||||
|
import me.shedaniel.architectury.event.Event;
|
||||||
|
import me.shedaniel.architectury.event.EventFactory;
|
||||||
|
import net.fabricmc.api.EnvType;
|
||||||
|
import net.fabricmc.api.Environment;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.server.MinecraftServer;
|
||||||
|
|
||||||
|
public interface LifecycleEvent {
|
||||||
|
@Environment(EnvType.CLIENT)
|
||||||
|
Event<ClientState> CLIENT_STARTED = EventFactory.createLoop(ClientState.class);
|
||||||
|
@Environment(EnvType.CLIENT)
|
||||||
|
Event<ClientState> CLIENT_STOPPING = EventFactory.createLoop(ClientState.class);
|
||||||
|
Event<ServerState> SERVER_STARTING = EventFactory.createLoop(ServerState.class);
|
||||||
|
Event<ServerState> SERVER_STARTED = EventFactory.createLoop(ServerState.class);
|
||||||
|
Event<ServerState> SERVER_STOPPING = EventFactory.createLoop(ServerState.class);
|
||||||
|
Event<ServerState> SERVER_STOPPED = EventFactory.createLoop(ServerState.class);
|
||||||
|
|
||||||
|
interface InstanceState<T> {
|
||||||
|
void stateChanged(T instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Environment(EnvType.CLIENT)
|
||||||
|
interface ClientState extends InstanceState<Minecraft> {}
|
||||||
|
|
||||||
|
interface ServerState extends InstanceState<MinecraftServer> {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 shedaniel
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package me.shedaniel.architectury.event.events;
|
||||||
|
|
||||||
|
import me.shedaniel.architectury.event.Event;
|
||||||
|
import me.shedaniel.architectury.event.EventFactory;
|
||||||
|
import net.fabricmc.api.EnvType;
|
||||||
|
import net.fabricmc.api.Environment;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
|
import net.minecraft.server.MinecraftServer;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
|
||||||
|
public interface TickEvent<T> {
|
||||||
|
@Environment(EnvType.CLIENT)
|
||||||
|
Event<Client> CLIENT_PRE = EventFactory.createLoop(Client.class);
|
||||||
|
@Environment(EnvType.CLIENT)
|
||||||
|
Event<Client> CLIENT_POST = EventFactory.createLoop(Client.class);
|
||||||
|
Event<Server> SERVER_PRE = EventFactory.createLoop(Server.class);
|
||||||
|
Event<Server> SERVER_POST = EventFactory.createLoop(Server.class);
|
||||||
|
@Environment(EnvType.CLIENT)
|
||||||
|
Event<ClientWorld> CLIENT_WORLD_PRE = EventFactory.createLoop(ClientWorld.class);
|
||||||
|
@Environment(EnvType.CLIENT)
|
||||||
|
Event<ClientWorld> CLIENT_WORLD_POST = EventFactory.createLoop(ClientWorld.class);
|
||||||
|
Event<ServerWorld> SERVER_WORLD_PRE = EventFactory.createLoop(ServerWorld.class);
|
||||||
|
Event<ServerWorld> SERVER_WORLD_POST = EventFactory.createLoop(ServerWorld.class);
|
||||||
|
|
||||||
|
void tick(T instance);
|
||||||
|
|
||||||
|
@Environment(EnvType.CLIENT)
|
||||||
|
interface Client extends TickEvent<Minecraft> {}
|
||||||
|
|
||||||
|
interface Server extends TickEvent<MinecraftServer> {}
|
||||||
|
|
||||||
|
interface WorldTick<T extends Level> extends TickEvent<T> {}
|
||||||
|
|
||||||
|
@Environment(EnvType.CLIENT)
|
||||||
|
interface ClientWorld extends WorldTick<ClientLevel> {}
|
||||||
|
|
||||||
|
interface ServerWorld extends WorldTick<ServerLevel> {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 shedaniel
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package me.shedaniel.architectury.event.events;
|
||||||
|
|
||||||
|
import me.shedaniel.architectury.event.Event;
|
||||||
|
import me.shedaniel.architectury.event.EventFactory;
|
||||||
|
import net.fabricmc.api.EnvType;
|
||||||
|
import net.fabricmc.api.Environment;
|
||||||
|
import net.minecraft.network.chat.Component;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.item.TooltipFlag;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Environment(EnvType.CLIENT)
|
||||||
|
public interface TooltipEvent {
|
||||||
|
Event<Item> ITEM = EventFactory.createLoop(Item.class);
|
||||||
|
|
||||||
|
@Environment(EnvType.CLIENT)
|
||||||
|
interface Item {
|
||||||
|
void append(ItemStack stack, List<Component> lines, TooltipFlag flag);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,115 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 shedaniel
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package me.shedaniel.architectury.networking;
|
||||||
|
|
||||||
|
import me.shedaniel.architectury.ArchitecturyPopulator;
|
||||||
|
import me.shedaniel.architectury.Populatable;
|
||||||
|
import net.fabricmc.api.EnvType;
|
||||||
|
import net.fabricmc.api.Environment;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
|
import net.minecraft.network.protocol.Packet;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
import net.minecraft.world.entity.player.Player;
|
||||||
|
|
||||||
|
public final class NetworkManager {
|
||||||
|
@Populatable
|
||||||
|
private static final Impl IMPL = null;
|
||||||
|
|
||||||
|
public static void registerReceiver(Side side, ResourceLocation id, NetworkReceiver receiver) {
|
||||||
|
IMPL.registerReceiver(side, id, receiver);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Packet<?> toPacket(Side side, ResourceLocation id, FriendlyByteBuf buf) {
|
||||||
|
return IMPL.toPacket(side, id, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendToPlayer(ServerPlayer player, ResourceLocation id, FriendlyByteBuf buf) {
|
||||||
|
player.connection.send(toPacket(serverToClient(), id, buf));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendToPlayers(Iterable<ServerPlayer> players, ResourceLocation id, FriendlyByteBuf buf) {
|
||||||
|
Packet<?> packet = toPacket(serverToClient(), id, buf);
|
||||||
|
for (ServerPlayer player : players) {
|
||||||
|
player.connection.send(packet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Environment(EnvType.CLIENT)
|
||||||
|
public static void sendToServer(ResourceLocation id, FriendlyByteBuf buf) {
|
||||||
|
Minecraft.getInstance().getConnection().send(toPacket(clientToServer(), id, buf));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Environment(EnvType.CLIENT)
|
||||||
|
public static boolean canServerReceive(ResourceLocation id) {
|
||||||
|
return IMPL.canServerReceive(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean canPlayerReceive(ServerPlayer player, ResourceLocation id) {
|
||||||
|
return IMPL.canPlayerReceive(player, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface Impl {
|
||||||
|
void registerReceiver(Side side, ResourceLocation id, NetworkReceiver receiver);
|
||||||
|
|
||||||
|
Packet<?> toPacket(Side side, ResourceLocation id, FriendlyByteBuf buf);
|
||||||
|
|
||||||
|
@Environment(EnvType.CLIENT)
|
||||||
|
boolean canServerReceive(ResourceLocation id);
|
||||||
|
|
||||||
|
boolean canPlayerReceive(ServerPlayer player, ResourceLocation id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface NetworkReceiver {
|
||||||
|
void receive(FriendlyByteBuf buf, PacketContext context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface PacketContext {
|
||||||
|
Player getPlayer();
|
||||||
|
|
||||||
|
void queue(Runnable runnable);
|
||||||
|
|
||||||
|
EnvType getEnv();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Side s2c() {
|
||||||
|
return Side.S2C;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Side c2s() {
|
||||||
|
return Side.C2S;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Side serverToClient() {
|
||||||
|
return Side.S2C;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Side clientToServer() {
|
||||||
|
return Side.C2S;
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum Side {
|
||||||
|
S2C,
|
||||||
|
C2S
|
||||||
|
}
|
||||||
|
|
||||||
|
static {
|
||||||
|
ArchitecturyPopulator.populate(NetworkManager.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 shedaniel
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package me.shedaniel.architectury.platform;
|
||||||
|
|
||||||
|
import net.fabricmc.api.EnvType;
|
||||||
|
import net.fabricmc.api.Environment;
|
||||||
|
import net.minecraft.client.gui.screens.Screen;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public interface Mod {
|
||||||
|
@NotNull
|
||||||
|
String getModId();
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
String getVersion();
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
String getName();
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
String getDescription();
|
||||||
|
|
||||||
|
@Environment(EnvType.CLIENT)
|
||||||
|
void registerConfigurationScreen(ConfigurationScreenProvider provider);
|
||||||
|
|
||||||
|
@Environment(EnvType.CLIENT)
|
||||||
|
@FunctionalInterface
|
||||||
|
interface ConfigurationScreenProvider {
|
||||||
|
Screen provide(Screen parent);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 shedaniel
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package me.shedaniel.architectury.platform;
|
||||||
|
|
||||||
|
import me.shedaniel.architectury.Architectury;
|
||||||
|
import me.shedaniel.architectury.ArchitecturyPopulator;
|
||||||
|
import me.shedaniel.architectury.Populatable;
|
||||||
|
import net.fabricmc.api.EnvType;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
public final class Platform {
|
||||||
|
private Platform() {}
|
||||||
|
|
||||||
|
@Populatable
|
||||||
|
private static final Impl IMPL = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the current mod loader, either "fabric" or "forge"
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public static String getModLoader() {
|
||||||
|
return Architectury.getModLoader();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static Path getGameFolder() {
|
||||||
|
return IMPL.getGameFolder();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static Path getConfigFolder() {
|
||||||
|
return IMPL.getConfigFolder();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static EnvType getEnv() {
|
||||||
|
return IMPL.getEnv();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isModLoaded(String id) {
|
||||||
|
return IMPL.isModLoaded(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static Mod getMod(String id) {
|
||||||
|
return IMPL.getMod(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static Collection<Mod> getMods() {
|
||||||
|
return IMPL.getMods();
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface Impl {
|
||||||
|
Path getGameFolder();
|
||||||
|
|
||||||
|
Path getConfigFolder();
|
||||||
|
|
||||||
|
Path getModsFolder();
|
||||||
|
|
||||||
|
EnvType getEnv();
|
||||||
|
|
||||||
|
boolean isModLoaded(String id);
|
||||||
|
|
||||||
|
Mod getMod(String id);
|
||||||
|
|
||||||
|
Collection<Mod> getMods();
|
||||||
|
}
|
||||||
|
|
||||||
|
static {
|
||||||
|
ArchitecturyPopulator.populate(Platform.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 shedaniel
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package me.shedaniel.architectury.registry;
|
||||||
|
|
||||||
|
import me.shedaniel.architectury.ArchitecturyPopulator;
|
||||||
|
import me.shedaniel.architectury.Populatable;
|
||||||
|
import net.minecraft.resources.ResourceKey;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public final class Registries {
|
||||||
|
@Populatable
|
||||||
|
private static final Impl IMPL = null;
|
||||||
|
private static final Map<String, Registries> REGISTRIES = new HashMap<>();
|
||||||
|
private final RegistryProvider provider;
|
||||||
|
|
||||||
|
public static Registries get(String modId) {
|
||||||
|
return REGISTRIES.computeIfAbsent(modId, Registries::new);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Registries(String modId) {
|
||||||
|
this.provider = IMPL.get(modId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> Registry<T> get(ResourceKey<net.minecraft.core.Registry<T>> key) {
|
||||||
|
return this.provider.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
public <T> Registry<T> get(net.minecraft.core.Registry<T> registry) {
|
||||||
|
return this.provider.get(registry);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface Impl {
|
||||||
|
RegistryProvider get(String modId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface RegistryProvider {
|
||||||
|
<T> Registry<T> get(ResourceKey<net.minecraft.core.Registry<T>> key);
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
<T> Registry<T> get(net.minecraft.core.Registry<T> registry);
|
||||||
|
}
|
||||||
|
|
||||||
|
static {
|
||||||
|
ArchitecturyPopulator.populate(Registries.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 shedaniel
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package me.shedaniel.architectury.registry;
|
||||||
|
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
public interface Registry<T> {
|
||||||
|
Supplier<T> delegate(ResourceLocation id);
|
||||||
|
|
||||||
|
Supplier<T> register(ResourceLocation id, Supplier<T> supplier);
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
ResourceLocation getId(T obj);
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
T get(ResourceLocation id);
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package me.shedaniel.architectury.utils;
|
||||||
|
|
||||||
|
import me.shedaniel.architectury.ArchitecturyPopulator;
|
||||||
|
import me.shedaniel.architectury.Populatable;
|
||||||
|
import net.fabricmc.api.EnvType;
|
||||||
|
import net.fabricmc.api.Environment;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.server.MinecraftServer;
|
||||||
|
|
||||||
|
public final class GameInstance {
|
||||||
|
@Populatable
|
||||||
|
private static final Impl IMPL = null;
|
||||||
|
|
||||||
|
@Environment(EnvType.CLIENT)
|
||||||
|
public static Minecraft getClient() {
|
||||||
|
return Minecraft.getInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Environment(EnvType.SERVER)
|
||||||
|
public static MinecraftServer getServer() {
|
||||||
|
return IMPL.getServer();
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface Impl {
|
||||||
|
MinecraftServer getServer();
|
||||||
|
}
|
||||||
|
|
||||||
|
static {
|
||||||
|
ArchitecturyPopulator.populate(GameInstance.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
6
common/src/main/resources/fabric.mod.json
Normal file
6
common/src/main/resources/fabric.mod.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"_comment": "This file is here to make fabric loader load this on the Knot classloader.",
|
||||||
|
"schemaVersion": 1,
|
||||||
|
"id": "architectury-common",
|
||||||
|
"version": "0.0.1"
|
||||||
|
}
|
||||||
33
fabric/build.gradle
Normal file
33
fabric/build.gradle
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
plugins {
|
||||||
|
id "fabric-loom"
|
||||||
|
id "com.github.johnrengelman.shadow" version "5.0.0"
|
||||||
|
}
|
||||||
|
|
||||||
|
configurations {
|
||||||
|
shadow
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
minecraft("com.mojang:minecraft:${rootProject.architect.minecraft}")
|
||||||
|
mappings(minecraft.officialMojangMappings())
|
||||||
|
modCompile("net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}")
|
||||||
|
modCompile("net.fabricmc.fabric-api:fabric-api:${rootProject.fabric_api_version}")
|
||||||
|
modCompileOnly("io.github.prospector:modmenu:${rootProject.mod_menu_version}")
|
||||||
|
|
||||||
|
compile(project(":common")) {
|
||||||
|
transitive = false
|
||||||
|
}
|
||||||
|
shadow(project(":common")) {
|
||||||
|
transitive = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
shadowJar {
|
||||||
|
configurations = [project.configurations.shadow]
|
||||||
|
classifier "shadow"
|
||||||
|
}
|
||||||
|
|
||||||
|
remapJar {
|
||||||
|
dependsOn(shadowJar)
|
||||||
|
input.set(shadowJar.archivePath)
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 shedaniel
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package me.shedaniel.architectury.compat.fabric;
|
||||||
|
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
import io.github.prospector.modmenu.api.ConfigScreenFactory;
|
||||||
|
import io.github.prospector.modmenu.api.ModMenuApi;
|
||||||
|
import me.shedaniel.architectury.platform.fabric.PlatformImpl;
|
||||||
|
import me.shedaniel.architectury.platform.Mod;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class ModMenuCompatibility implements ModMenuApi {
|
||||||
|
private static final Map<String, ConfigScreenFactory<?>> FACTORIES = Maps.newHashMap();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, ConfigScreenFactory<?>> getProvidedConfigScreenFactories() {
|
||||||
|
validateMap();
|
||||||
|
return FACTORIES;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateMap() {
|
||||||
|
for (Map.Entry<String, Mod.ConfigurationScreenProvider> entry : PlatformImpl.CONFIG_SCREENS.entrySet()) {
|
||||||
|
if (!FACTORIES.containsKey(entry.getKey())) {
|
||||||
|
FACTORIES.put(entry.getKey(), entry.getValue()::provide);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 shedaniel
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package me.shedaniel.architectury.event.fabric;
|
||||||
|
|
||||||
|
import me.shedaniel.architectury.event.EventFactory;
|
||||||
|
import me.shedaniel.architectury.event.events.GuiEvent;
|
||||||
|
import me.shedaniel.architectury.event.events.LifecycleEvent;
|
||||||
|
import me.shedaniel.architectury.event.events.TickEvent;
|
||||||
|
import me.shedaniel.architectury.event.events.TooltipEvent;
|
||||||
|
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents;
|
||||||
|
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
|
||||||
|
import net.fabricmc.fabric.api.client.item.v1.ItemTooltipCallback;
|
||||||
|
import net.fabricmc.fabric.api.client.rendering.v1.HudRenderCallback;
|
||||||
|
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
|
||||||
|
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
|
||||||
|
|
||||||
|
public class EventFactoryImpl implements EventFactory.Impl {
|
||||||
|
@Override
|
||||||
|
public void registerClient() {
|
||||||
|
ClientLifecycleEvents.CLIENT_STARTED.register(LifecycleEvent.CLIENT_STARTED.invoker()::stateChanged);
|
||||||
|
ClientLifecycleEvents.CLIENT_STOPPING.register(LifecycleEvent.CLIENT_STOPPING.invoker()::stateChanged);
|
||||||
|
|
||||||
|
ClientTickEvents.START_CLIENT_TICK.register(TickEvent.CLIENT_PRE.invoker()::tick);
|
||||||
|
ClientTickEvents.END_CLIENT_TICK.register(TickEvent.CLIENT_POST.invoker()::tick);
|
||||||
|
ClientTickEvents.START_WORLD_TICK.register(TickEvent.CLIENT_WORLD_PRE.invoker()::tick);
|
||||||
|
ClientTickEvents.END_WORLD_TICK.register(TickEvent.CLIENT_WORLD_POST.invoker()::tick);
|
||||||
|
|
||||||
|
ItemTooltipCallback.EVENT.register((itemStack, tooltipFlag, list) -> TooltipEvent.ITEM.invoker().append(itemStack, list, tooltipFlag));
|
||||||
|
HudRenderCallback.EVENT.register(GuiEvent.RENDER_HUD.invoker()::renderHud);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void registerCommon() {
|
||||||
|
ServerLifecycleEvents.SERVER_STARTING.register(LifecycleEvent.SERVER_STARTING.invoker()::stateChanged);
|
||||||
|
ServerLifecycleEvents.SERVER_STARTED.register(LifecycleEvent.SERVER_STARTED.invoker()::stateChanged);
|
||||||
|
ServerLifecycleEvents.SERVER_STOPPING.register(LifecycleEvent.SERVER_STOPPING.invoker()::stateChanged);
|
||||||
|
ServerLifecycleEvents.SERVER_STOPPED.register(LifecycleEvent.SERVER_STOPPED.invoker()::stateChanged);
|
||||||
|
|
||||||
|
ServerTickEvents.START_SERVER_TICK.register(TickEvent.SERVER_PRE.invoker()::tick);
|
||||||
|
ServerTickEvents.END_SERVER_TICK.register(TickEvent.SERVER_POST.invoker()::tick);
|
||||||
|
ServerTickEvents.START_WORLD_TICK.register(TickEvent.SERVER_WORLD_PRE.invoker()::tick);
|
||||||
|
ServerTickEvents.END_WORLD_TICK.register(TickEvent.SERVER_WORLD_POST.invoker()::tick);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void registerServer() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
package me.shedaniel.architectury.networking.fabric;
|
||||||
|
|
||||||
|
import me.shedaniel.architectury.networking.NetworkManager;
|
||||||
|
import me.shedaniel.architectury.networking.NetworkManager.NetworkReceiver;
|
||||||
|
import net.fabricmc.api.EnvType;
|
||||||
|
import net.fabricmc.api.Environment;
|
||||||
|
import net.fabricmc.fabric.api.network.ClientSidePacketRegistry;
|
||||||
|
import net.fabricmc.fabric.api.network.PacketContext;
|
||||||
|
import net.fabricmc.fabric.api.network.ServerSidePacketRegistry;
|
||||||
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
|
import net.minecraft.network.protocol.Packet;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
import net.minecraft.world.entity.player.Player;
|
||||||
|
|
||||||
|
public class NetworkManagerImpl implements NetworkManager.Impl {
|
||||||
|
@Override
|
||||||
|
public void registerReceiver(NetworkManager.Side side, ResourceLocation id, NetworkReceiver receiver) {
|
||||||
|
if (side == NetworkManager.Side.C2S) {
|
||||||
|
registerC2SReceiver(id, receiver);
|
||||||
|
} else if (side == NetworkManager.Side.S2C) {
|
||||||
|
registerS2CReceiver(id, receiver);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void registerC2SReceiver(ResourceLocation id, NetworkReceiver receiver) {
|
||||||
|
ServerSidePacketRegistry.INSTANCE.register(id, (packetContext, buf) -> receiver.receive(buf, to(packetContext)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Environment(EnvType.CLIENT)
|
||||||
|
private void registerS2CReceiver(ResourceLocation id, NetworkReceiver receiver) {
|
||||||
|
ClientSidePacketRegistry.INSTANCE.register(id, (packetContext, buf) -> receiver.receive(buf, to(packetContext)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private NetworkManager.PacketContext to(PacketContext context) {
|
||||||
|
return new NetworkManager.PacketContext() {
|
||||||
|
@Override
|
||||||
|
public Player getPlayer() {
|
||||||
|
return context.getPlayer();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void queue(Runnable runnable) {
|
||||||
|
context.getTaskQueue().execute(runnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EnvType getEnv() {
|
||||||
|
return context.getPacketEnvironment();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Packet<?> toPacket(NetworkManager.Side side, ResourceLocation id, FriendlyByteBuf buf) {
|
||||||
|
if (side == NetworkManager.Side.C2S) {
|
||||||
|
return toC2SPacket(id, buf);
|
||||||
|
} else if (side == NetworkManager.Side.S2C) {
|
||||||
|
return toS2CPacket(id, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new IllegalArgumentException("Invalid side: " + side);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canServerReceive(ResourceLocation id) {
|
||||||
|
return ClientSidePacketRegistry.INSTANCE.canServerReceive(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canPlayerReceive(ServerPlayer player, ResourceLocation id) {
|
||||||
|
return ServerSidePacketRegistry.INSTANCE.canPlayerReceive(player, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Environment(EnvType.CLIENT)
|
||||||
|
private Packet<?> toC2SPacket(ResourceLocation id, FriendlyByteBuf buf) {
|
||||||
|
return ClientSidePacketRegistry.INSTANCE.toPacket(id, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Packet<?> toS2CPacket(ResourceLocation id, FriendlyByteBuf buf) {
|
||||||
|
return ServerSidePacketRegistry.INSTANCE.toPacket(id, buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 shedaniel
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package me.shedaniel.architectury.platform.fabric;
|
||||||
|
|
||||||
|
import me.shedaniel.architectury.platform.Mod;
|
||||||
|
import me.shedaniel.architectury.platform.Platform;
|
||||||
|
import net.fabricmc.api.EnvType;
|
||||||
|
import net.fabricmc.loader.api.FabricLoader;
|
||||||
|
import net.fabricmc.loader.api.ModContainer;
|
||||||
|
import net.fabricmc.loader.api.metadata.ModMetadata;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class PlatformImpl implements Platform.Impl {
|
||||||
|
public static final Map<String, Mod.ConfigurationScreenProvider> CONFIG_SCREENS = new HashMap<>();
|
||||||
|
private final Map<String, Mod> mods = new HashMap<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Path getGameFolder() {
|
||||||
|
return FabricLoader.getInstance().getGameDir();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Path getConfigFolder() {
|
||||||
|
return FabricLoader.getInstance().getConfigDir();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Path getModsFolder() {
|
||||||
|
return getGameFolder().resolve("mods");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EnvType getEnv() {
|
||||||
|
return FabricLoader.getInstance().getEnvironmentType();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isModLoaded(String id) {
|
||||||
|
return FabricLoader.getInstance().isModLoaded(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Mod getMod(String id) {
|
||||||
|
return this.mods.computeIfAbsent(id, ModImpl::new);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<Mod> getMods() {
|
||||||
|
for (ModContainer mod : FabricLoader.getInstance().getAllMods()) {
|
||||||
|
getMod(mod.getMetadata().getId());
|
||||||
|
}
|
||||||
|
return this.mods.values();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ModImpl implements Mod {
|
||||||
|
private final ModMetadata metadata;
|
||||||
|
|
||||||
|
public ModImpl(String id) {
|
||||||
|
this.metadata = FabricLoader.getInstance().getModContainer(id).get().getMetadata();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull String getModId() {
|
||||||
|
return metadata.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull String getVersion() {
|
||||||
|
return metadata.getVersion().getFriendlyString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull String getName() {
|
||||||
|
return metadata.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull String getDescription() {
|
||||||
|
return metadata.getDescription();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void registerConfigurationScreen(ConfigurationScreenProvider provider) {
|
||||||
|
if (CONFIG_SCREENS.containsKey(getModId()))
|
||||||
|
throw new IllegalStateException("Can not register configuration screen for mod '" + getModId() + "' because it was already registered!");
|
||||||
|
CONFIG_SCREENS.put(getModId(), provider);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 shedaniel
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package me.shedaniel.architectury.registry.fabric;
|
||||||
|
|
||||||
|
import me.shedaniel.architectury.registry.Registries;
|
||||||
|
import me.shedaniel.architectury.registry.Registry;
|
||||||
|
import net.minecraft.resources.ResourceKey;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.util.LazyLoadedValue;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
public class RegistriesImpl implements Registries.Impl {
|
||||||
|
@Override
|
||||||
|
public Registries.RegistryProvider get(String modId) {
|
||||||
|
return RegistryProviderImpl.INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum RegistryProviderImpl implements Registries.RegistryProvider {
|
||||||
|
INSTANCE;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> Registry<T> get(ResourceKey<net.minecraft.core.Registry<T>> key) {
|
||||||
|
return new RegistryImpl<>((net.minecraft.core.Registry<T>) net.minecraft.core.Registry.REGISTRY.get(key.location()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> Registry<T> get(net.minecraft.core.Registry<T> registry) {
|
||||||
|
return new RegistryImpl<>(registry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class RegistryImpl<T> implements Registry<T> {
|
||||||
|
private net.minecraft.core.Registry<T> delegate;
|
||||||
|
|
||||||
|
public RegistryImpl(net.minecraft.core.Registry<T> delegate) {
|
||||||
|
this.delegate = delegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Supplier<T> delegate(ResourceLocation id) {
|
||||||
|
LazyLoadedValue<T> value = new LazyLoadedValue<>(() -> get(id));
|
||||||
|
return value::get;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Supplier<T> register(ResourceLocation id, Supplier<T> supplier) {
|
||||||
|
net.minecraft.core.Registry.register(delegate, id, supplier.get());
|
||||||
|
return delegate(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable ResourceLocation getId(T obj) {
|
||||||
|
return delegate.getKey(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable T get(ResourceLocation id) {
|
||||||
|
return delegate.get(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package me.shedaniel.architectury.utils.fabric;
|
||||||
|
|
||||||
|
import me.shedaniel.architectury.event.events.LifecycleEvent;
|
||||||
|
import me.shedaniel.architectury.platform.Platform;
|
||||||
|
import me.shedaniel.architectury.utils.GameInstance;
|
||||||
|
import net.fabricmc.api.EnvType;
|
||||||
|
import net.fabricmc.api.Environment;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.server.MinecraftServer;
|
||||||
|
|
||||||
|
public class GameInstanceImpl implements GameInstance.Impl {
|
||||||
|
private static MinecraftServer server = null;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MinecraftServer getServer() {
|
||||||
|
MinecraftServer server = null;
|
||||||
|
if (GameInstanceImpl.server != null) server = GameInstanceImpl.server;
|
||||||
|
if (Platform.getEnv() == EnvType.CLIENT) {
|
||||||
|
server = getServerFromClient();
|
||||||
|
}
|
||||||
|
return server;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void init() {
|
||||||
|
LifecycleEvent.SERVER_STARTING.register(server -> GameInstanceImpl.server = server);
|
||||||
|
LifecycleEvent.SERVER_STOPPED.register(server -> GameInstanceImpl.server = null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Environment(EnvType.CLIENT)
|
||||||
|
private static MinecraftServer getServerFromClient() {
|
||||||
|
return Minecraft.getInstance().getSingleplayerServer();
|
||||||
|
}
|
||||||
|
}
|
||||||
26
fabric/src/main/resources/fabric.mod.json
Normal file
26
fabric/src/main/resources/fabric.mod.json
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"schemaVersion": 1,
|
||||||
|
"id": "architectury",
|
||||||
|
"version": "${version}",
|
||||||
|
"name": "Architectury",
|
||||||
|
"description": "This is an example description! Tell everyone what your mod is about!",
|
||||||
|
"authors": [
|
||||||
|
"shedaniel"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"environment": "*",
|
||||||
|
"mixins": [
|
||||||
|
"architectury.mixins.json"
|
||||||
|
],
|
||||||
|
"entrypoints": {
|
||||||
|
"main": [
|
||||||
|
"me.shedaniel.architectury.utils.fabric.GameInstanceImpl::init"
|
||||||
|
],
|
||||||
|
"modmenu": [
|
||||||
|
"me.shedaniel.architectury.compat.fabric.ModMenuCompatibility"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"depends": {
|
||||||
|
"minecraft": ">=1.16.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
71
forge/build.gradle
Normal file
71
forge/build.gradle
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
buildscript {
|
||||||
|
repositories {
|
||||||
|
maven { url "https://files.minecraftforge.net/maven" }
|
||||||
|
jcenter()
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
dependencies {
|
||||||
|
classpath(group: "net.minecraftforge.gradle", name: "ForgeGradle", version: "3.+", changing: true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
id "com.github.johnrengelman.shadow" version "5.0.0"
|
||||||
|
id "eclipse"
|
||||||
|
}
|
||||||
|
|
||||||
|
apply plugin: "net.minecraftforge.gradle"
|
||||||
|
|
||||||
|
minecraft {
|
||||||
|
mappings(channel: "official", version: rootProject.architect.minecraft)
|
||||||
|
accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg')
|
||||||
|
runs {
|
||||||
|
client {
|
||||||
|
workingDirectory project.file("run")
|
||||||
|
mods {
|
||||||
|
examplemod {
|
||||||
|
source sourceSets.main
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
server {
|
||||||
|
workingDirectory project.file("run")
|
||||||
|
mods {
|
||||||
|
examplemod {
|
||||||
|
source sourceSets.main
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
jcenter()
|
||||||
|
maven { url "https://files.minecraftforge.net/maven" }
|
||||||
|
}
|
||||||
|
|
||||||
|
configurations {
|
||||||
|
shadow
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
minecraft("net.minecraftforge:forge:${rootProject.architect.minecraft}-${rootProject.forge_version}")
|
||||||
|
|
||||||
|
compile(project(path: ":common", configuration: "mcpGenerateMod")) {
|
||||||
|
transitive = false
|
||||||
|
}
|
||||||
|
shadow(project(path: ":common", configuration: "mcp")) {
|
||||||
|
transitive = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
shadowJar {
|
||||||
|
exclude "fabric.mod.json"
|
||||||
|
|
||||||
|
configurations = [project.configurations.shadow]
|
||||||
|
classifier null
|
||||||
|
}
|
||||||
|
|
||||||
|
reobf {
|
||||||
|
shadowJar {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,124 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 shedaniel
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package me.shedaniel.architectury.event.forge;
|
||||||
|
|
||||||
|
import me.shedaniel.architectury.event.EventFactory;
|
||||||
|
import me.shedaniel.architectury.event.events.GuiEvent;
|
||||||
|
import me.shedaniel.architectury.event.events.LifecycleEvent;
|
||||||
|
import me.shedaniel.architectury.event.events.TickEvent;
|
||||||
|
import me.shedaniel.architectury.event.events.TooltipEvent;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.world.server.ServerWorld;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
|
import net.minecraftforge.client.event.RenderGameOverlayEvent;
|
||||||
|
import net.minecraftforge.common.MinecraftForge;
|
||||||
|
import net.minecraftforge.event.TickEvent.ClientTickEvent;
|
||||||
|
import net.minecraftforge.event.TickEvent.Phase;
|
||||||
|
import net.minecraftforge.event.TickEvent.ServerTickEvent;
|
||||||
|
import net.minecraftforge.event.TickEvent.WorldTickEvent;
|
||||||
|
import net.minecraftforge.event.entity.player.ItemTooltipEvent;
|
||||||
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
|
import net.minecraftforge.fml.LogicalSide;
|
||||||
|
import net.minecraftforge.fml.event.server.FMLServerStartedEvent;
|
||||||
|
import net.minecraftforge.fml.event.server.FMLServerStartingEvent;
|
||||||
|
import net.minecraftforge.fml.event.server.FMLServerStoppedEvent;
|
||||||
|
import net.minecraftforge.fml.event.server.FMLServerStoppingEvent;
|
||||||
|
import net.minecraftforge.fml.server.ServerLifecycleHooks;
|
||||||
|
|
||||||
|
public class EventFactoryImpl implements EventFactory.Impl {
|
||||||
|
@Override
|
||||||
|
public void registerClient() {
|
||||||
|
MinecraftForge.EVENT_BUS.register(Client.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void registerCommon() {
|
||||||
|
MinecraftForge.EVENT_BUS.register(Common.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void registerServer() {
|
||||||
|
MinecraftForge.EVENT_BUS.register(Server.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
public static class Client {
|
||||||
|
@SubscribeEvent
|
||||||
|
public static void event(ItemTooltipEvent event) {
|
||||||
|
TooltipEvent.ITEM.invoker().append(event.getItemStack(), event.getToolTip(), event.getFlags());
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public static void event(ClientTickEvent event) {
|
||||||
|
if (event.phase == Phase.START)
|
||||||
|
TickEvent.CLIENT_PRE.invoker().tick(Minecraft.getInstance());
|
||||||
|
else if (event.phase == Phase.END)
|
||||||
|
TickEvent.CLIENT_POST.invoker().tick(Minecraft.getInstance());
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public static void event(RenderGameOverlayEvent.Post event) {
|
||||||
|
GuiEvent.RENDER_HUD.invoker().renderHud(event.getMatrixStack(), event.getPartialTicks());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Common {
|
||||||
|
@SubscribeEvent
|
||||||
|
public static void event(ServerTickEvent event) {
|
||||||
|
if (event.phase == Phase.START)
|
||||||
|
TickEvent.SERVER_PRE.invoker().tick(ServerLifecycleHooks.getCurrentServer());
|
||||||
|
else if (event.phase == Phase.END)
|
||||||
|
TickEvent.SERVER_POST.invoker().tick(ServerLifecycleHooks.getCurrentServer());
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public static void event(WorldTickEvent event) {
|
||||||
|
if (event.side == LogicalSide.SERVER) {
|
||||||
|
if (event.phase == Phase.START)
|
||||||
|
TickEvent.SERVER_WORLD_PRE.invoker().tick((ServerWorld) event.world);
|
||||||
|
else if (event.phase == Phase.END)
|
||||||
|
TickEvent.SERVER_WORLD_POST.invoker().tick((ServerWorld) event.world);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public static void event(FMLServerStartingEvent event) {
|
||||||
|
LifecycleEvent.SERVER_STARTING.invoker().stateChanged(event.getServer());
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public static void event(FMLServerStartedEvent event) {
|
||||||
|
LifecycleEvent.SERVER_STARTED.invoker().stateChanged(event.getServer());
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public static void event(FMLServerStoppingEvent event) {
|
||||||
|
LifecycleEvent.SERVER_STOPPING.invoker().stateChanged(event.getServer());
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public static void event(FMLServerStoppedEvent event) {
|
||||||
|
LifecycleEvent.SERVER_STOPPED.invoker().stateChanged(event.getServer());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnlyIn(Dist.DEDICATED_SERVER)
|
||||||
|
public static class Server {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package me.shedaniel.architectury.networking.forge;
|
||||||
|
|
||||||
|
import me.shedaniel.architectury.networking.NetworkManager;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
|
import net.minecraftforge.client.event.ClientPlayerNetworkEvent;
|
||||||
|
import net.minecraftforge.common.MinecraftForge;
|
||||||
|
import net.minecraftforge.fml.network.NetworkEvent;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
import static me.shedaniel.architectury.networking.forge.NetworkManagerImpl.C2S;
|
||||||
|
import static me.shedaniel.architectury.networking.forge.NetworkManagerImpl.SYNC_IDS;
|
||||||
|
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
public class ClientNetworkingManager {
|
||||||
|
public static Consumer<NetworkManagerImpl> initClient() {
|
||||||
|
NetworkManagerImpl.CHANNEL.addListener(NetworkManagerImpl.createPacketHandler(NetworkEvent.ServerCustomPayloadEvent.class, NetworkManagerImpl.S2C));
|
||||||
|
MinecraftForge.EVENT_BUS.<ClientPlayerNetworkEvent.LoggedOutEvent>addListener(event -> NetworkManagerImpl.serverReceivables.clear());
|
||||||
|
|
||||||
|
return impl -> impl.registerS2CReceiver(SYNC_IDS, (buffer, context) -> {
|
||||||
|
Set<ResourceLocation> receivables = NetworkManagerImpl.serverReceivables;
|
||||||
|
int size = buffer.readInt();
|
||||||
|
receivables.clear();
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
receivables.add(buffer.readResourceLocation());
|
||||||
|
}
|
||||||
|
NetworkManager.sendToServer(SYNC_IDS, NetworkManagerImpl.sendSyncPacket(C2S));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PlayerEntity getClientPlayer() {
|
||||||
|
return Minecraft.getInstance().player;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,137 @@
|
|||||||
|
package me.shedaniel.architectury.networking.forge;
|
||||||
|
|
||||||
|
|
||||||
|
import com.google.common.collect.*;
|
||||||
|
import io.netty.buffer.Unpooled;
|
||||||
|
import me.shedaniel.architectury.networking.NetworkManager;
|
||||||
|
import me.shedaniel.architectury.networking.NetworkManager.NetworkReceiver;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||||
|
import net.minecraft.network.IPacket;
|
||||||
|
import net.minecraft.network.PacketBuffer;
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
|
import net.minecraftforge.common.MinecraftForge;
|
||||||
|
import net.minecraftforge.event.entity.player.PlayerEvent;
|
||||||
|
import net.minecraftforge.fml.DistExecutor;
|
||||||
|
import net.minecraftforge.fml.LogicalSide;
|
||||||
|
import net.minecraftforge.fml.network.NetworkDirection;
|
||||||
|
import net.minecraftforge.fml.network.NetworkEvent;
|
||||||
|
import net.minecraftforge.fml.network.NetworkRegistry;
|
||||||
|
import net.minecraftforge.fml.network.event.EventNetworkChannel;
|
||||||
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
public class NetworkManagerImpl implements NetworkManager.Impl {
|
||||||
|
@Override
|
||||||
|
public void registerReceiver(NetworkManager.Side side, ResourceLocation id, NetworkReceiver receiver) {
|
||||||
|
if (side == NetworkManager.Side.C2S) {
|
||||||
|
registerC2SReceiver(id, receiver);
|
||||||
|
} else if (side == NetworkManager.Side.S2C) {
|
||||||
|
registerS2CReceiver(id, receiver);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IPacket<?> toPacket(NetworkManager.Side side, ResourceLocation id, PacketBuffer buffer) {
|
||||||
|
PacketBuffer packetBuffer = new PacketBuffer(Unpooled.buffer());
|
||||||
|
packetBuffer.writeResourceLocation(id);
|
||||||
|
packetBuffer.writeBytes(buffer);
|
||||||
|
return (side == NetworkManager.Side.C2S ? NetworkDirection.PLAY_TO_SERVER : NetworkDirection.PLAY_TO_CLIENT).buildPacket(Pair.of(packetBuffer, 0), CHANNEL_ID).getThis();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final ResourceLocation CHANNEL_ID = new ResourceLocation("architectury:network");
|
||||||
|
static final ResourceLocation SYNC_IDS = new ResourceLocation("architectury:sync_ids");
|
||||||
|
static final EventNetworkChannel CHANNEL = NetworkRegistry.newEventChannel(CHANNEL_ID, () -> "1", version -> true, version -> true);
|
||||||
|
static final Map<ResourceLocation, NetworkReceiver> S2C = Maps.newHashMap();
|
||||||
|
static final Map<ResourceLocation, NetworkReceiver> C2S = Maps.newHashMap();
|
||||||
|
static final Set<ResourceLocation> serverReceivables = Sets.newHashSet();
|
||||||
|
private static final Multimap<PlayerEntity, ResourceLocation> clientReceivables = Multimaps.newMultimap(Maps.newHashMap(), Sets::newHashSet);
|
||||||
|
|
||||||
|
public NetworkManagerImpl() {
|
||||||
|
CHANNEL.addListener(createPacketHandler(NetworkEvent.ClientCustomPayloadEvent.class, C2S));
|
||||||
|
|
||||||
|
DistExecutor.unsafeCallWhenOn(Dist.CLIENT, () -> ClientNetworkingManager::initClient).accept(this);
|
||||||
|
|
||||||
|
MinecraftForge.EVENT_BUS.<PlayerEvent.PlayerLoggedInEvent>addListener(event -> NetworkManager.sendToPlayer((ServerPlayerEntity) event.getPlayer(), SYNC_IDS, sendSyncPacket(C2S)));
|
||||||
|
MinecraftForge.EVENT_BUS.<PlayerEvent.PlayerLoggedOutEvent>addListener(event -> clientReceivables.removeAll(event.getPlayer()));
|
||||||
|
|
||||||
|
registerC2SReceiver(SYNC_IDS, (buffer, context) -> {
|
||||||
|
Set<ResourceLocation> receivables = (Set<ResourceLocation>) clientReceivables.get(context.getPlayer());
|
||||||
|
int size = buffer.readInt();
|
||||||
|
receivables.clear();
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
receivables.add(buffer.readResourceLocation());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static <T extends NetworkEvent> Consumer<T> createPacketHandler(Class<T> clazz, Map<ResourceLocation, NetworkReceiver> map) {
|
||||||
|
return event -> {
|
||||||
|
if (event.getClass() != clazz) return;
|
||||||
|
NetworkEvent.Context context = event.getSource().get();
|
||||||
|
if (context.getPacketHandled()) return;
|
||||||
|
PacketBuffer buffer = new PacketBuffer(event.getPayload().copy());
|
||||||
|
ResourceLocation type = buffer.readResourceLocation();
|
||||||
|
NetworkReceiver receiver = map.get(type);
|
||||||
|
|
||||||
|
if (receiver != null) {
|
||||||
|
receiver.receive(buffer, new NetworkManager.PacketContext() {
|
||||||
|
@Override
|
||||||
|
public PlayerEntity getPlayer() {
|
||||||
|
return getEnv() == Dist.CLIENT ? getClientPlayer() : context.getSender();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void queue(Runnable runnable) {
|
||||||
|
context.enqueueWork(runnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dist getEnv() {
|
||||||
|
return context.getDirection().getReceptionSide() == LogicalSide.CLIENT ? Dist.CLIENT : Dist.DEDICATED_SERVER;
|
||||||
|
}
|
||||||
|
|
||||||
|
private PlayerEntity getClientPlayer() {
|
||||||
|
return DistExecutor.unsafeCallWhenOn(Dist.CLIENT, () -> ClientNetworkingManager::getClientPlayer);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
context.setPacketHandled(true);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
public void registerS2CReceiver(ResourceLocation id, NetworkReceiver receiver) {
|
||||||
|
S2C.put(id, receiver);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void registerC2SReceiver(ResourceLocation id, NetworkReceiver receiver) {
|
||||||
|
C2S.put(id, receiver);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canServerReceive(ResourceLocation id) {
|
||||||
|
return serverReceivables.contains(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canPlayerReceive(ServerPlayerEntity player, ResourceLocation id) {
|
||||||
|
return clientReceivables.get(player).contains(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
static PacketBuffer sendSyncPacket(Map<ResourceLocation, NetworkReceiver> map) {
|
||||||
|
List<ResourceLocation> availableIds = Lists.newArrayList(map.keySet());
|
||||||
|
PacketBuffer packetBuffer = new PacketBuffer(Unpooled.buffer());
|
||||||
|
packetBuffer.writeInt(availableIds.size());
|
||||||
|
for (ResourceLocation availableId : availableIds) {
|
||||||
|
packetBuffer.writeResourceLocation(availableId);
|
||||||
|
}
|
||||||
|
return packetBuffer;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 shedaniel
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package me.shedaniel.architectury.platform.forge;
|
||||||
|
|
||||||
|
import net.minecraftforge.eventbus.api.IEventBus;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public final class EventBuses {
|
||||||
|
private EventBuses() {}
|
||||||
|
|
||||||
|
private static final Map<String, IEventBus> EVENT_BUS_MAP = new HashMap<>();
|
||||||
|
|
||||||
|
public static void registerModEventBus(String modId, IEventBus bus) {
|
||||||
|
IEventBus previous = EVENT_BUS_MAP.put(modId, bus);
|
||||||
|
if (previous != null) {
|
||||||
|
EVENT_BUS_MAP.put(modId, previous);
|
||||||
|
throw new IllegalStateException("Can't register event bus for mod '" + modId + "' because it was previously registered!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Optional<IEventBus> getModEventBus(String modId) {
|
||||||
|
return Optional.ofNullable(EVENT_BUS_MAP.get(modId));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,114 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 shedaniel
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package me.shedaniel.architectury.platform.forge;
|
||||||
|
|
||||||
|
import me.shedaniel.architectury.platform.Mod;
|
||||||
|
import me.shedaniel.architectury.platform.Platform;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.fml.ExtensionPoint;
|
||||||
|
import net.minecraftforge.fml.ModContainer;
|
||||||
|
import net.minecraftforge.fml.ModList;
|
||||||
|
import net.minecraftforge.fml.loading.FMLEnvironment;
|
||||||
|
import net.minecraftforge.fml.loading.FMLPaths;
|
||||||
|
import net.minecraftforge.forgespi.language.IModInfo;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class PlatformImpl implements Platform.Impl {
|
||||||
|
private final Map<String, Mod> mods = new HashMap<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Path getGameFolder() {
|
||||||
|
return FMLPaths.GAMEDIR.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Path getConfigFolder() {
|
||||||
|
return FMLPaths.CONFIGDIR.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Path getModsFolder() {
|
||||||
|
return FMLPaths.MODSDIR.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dist getEnv() {
|
||||||
|
return FMLEnvironment.dist;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isModLoaded(String id) {
|
||||||
|
return ModList.get().isLoaded(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Mod getMod(String id) {
|
||||||
|
return this.mods.computeIfAbsent(id, ModImpl::new);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<Mod> getMods() {
|
||||||
|
for (IModInfo mod : ModList.get().getMods()) {
|
||||||
|
getMod(mod.getModId());
|
||||||
|
}
|
||||||
|
return this.mods.values();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ModImpl implements Mod {
|
||||||
|
private final ModContainer container;
|
||||||
|
private final IModInfo metadata;
|
||||||
|
|
||||||
|
public ModImpl(String id) {
|
||||||
|
this.container = ModList.get().getModContainerById(id).get();
|
||||||
|
this.metadata = container.getModInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Nonnull
|
||||||
|
public String getModId() {
|
||||||
|
return metadata.getModId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Nonnull
|
||||||
|
public String getVersion() {
|
||||||
|
return metadata.getVersion().toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Nonnull
|
||||||
|
public String getName() {
|
||||||
|
return metadata.getDisplayName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Nonnull
|
||||||
|
public String getDescription() {
|
||||||
|
return metadata.getDescription();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void registerConfigurationScreen(ConfigurationScreenProvider configurationScreenProvider) {
|
||||||
|
container.registerExtensionPoint(ExtensionPoint.CONFIGGUIFACTORY, () -> (minecraft, screen) -> configurationScreenProvider.provide(screen));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,150 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 shedaniel
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package me.shedaniel.architectury.registry.forge;
|
||||||
|
|
||||||
|
import com.google.common.collect.HashBasedTable;
|
||||||
|
import com.google.common.collect.Table;
|
||||||
|
import me.shedaniel.architectury.platform.forge.EventBuses;
|
||||||
|
import me.shedaniel.architectury.registry.Registries;
|
||||||
|
import me.shedaniel.architectury.registry.Registry;
|
||||||
|
import net.minecraft.util.LazyValue;
|
||||||
|
import net.minecraft.util.RegistryKey;
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
import net.minecraftforge.event.RegistryEvent;
|
||||||
|
import net.minecraftforge.eventbus.api.IEventBus;
|
||||||
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
|
import net.minecraftforge.fml.RegistryObject;
|
||||||
|
import net.minecraftforge.registries.IForgeRegistry;
|
||||||
|
import net.minecraftforge.registries.IForgeRegistryEntry;
|
||||||
|
import net.minecraftforge.registries.RegistryManager;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
public class RegistriesImpl implements Registries.Impl {
|
||||||
|
@Override
|
||||||
|
public Registries.RegistryProvider get(String modId) {
|
||||||
|
return new RegistryProviderImpl(modId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class RegistryProviderImpl implements Registries.RegistryProvider {
|
||||||
|
private final String modId;
|
||||||
|
private final IEventBus eventBus;
|
||||||
|
private final Table<Type, RegistryObject<?>, Supplier<? extends IForgeRegistryEntry<?>>> registry = HashBasedTable.create();
|
||||||
|
|
||||||
|
public RegistryProviderImpl(String modId) {
|
||||||
|
this.modId = modId;
|
||||||
|
this.eventBus = EventBuses.getModEventBus(modId).orElseThrow(() -> new IllegalStateException("Can't get event bus for mod '" + modId + "' because it was not registered!"));
|
||||||
|
this.eventBus.register(new EventListener());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> Registry<T> get(RegistryKey<net.minecraft.util.registry.Registry<T>> registryKey) {
|
||||||
|
return new ForgeBackedRegistryImpl<>(registry, (IForgeRegistry) RegistryManager.ACTIVE.getRegistry(registryKey.location()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> Registry<T> get(net.minecraft.util.registry.Registry<T> registry) {
|
||||||
|
return new VanillaBackedRegistryImpl<>(registry);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class EventListener {
|
||||||
|
@SubscribeEvent
|
||||||
|
public void handleEvent(RegistryEvent.Register event) {
|
||||||
|
IForgeRegistry registry = event.getRegistry();
|
||||||
|
|
||||||
|
for (Map.Entry<Type, Map<RegistryObject<?>, Supplier<? extends IForgeRegistryEntry<?>>>> row : RegistryProviderImpl.this.registry.rowMap().entrySet()) {
|
||||||
|
if (row.getKey() == event.getGenericType()) {
|
||||||
|
for (Map.Entry<RegistryObject<?>, Supplier<? extends IForgeRegistryEntry<?>>> entry : row.getValue().entrySet()) {
|
||||||
|
registry.register(entry.getValue().get());
|
||||||
|
entry.getKey().updateReference(registry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class VanillaBackedRegistryImpl<T> implements Registry<T> {
|
||||||
|
private net.minecraft.util.registry.Registry<T> delegate;
|
||||||
|
|
||||||
|
public VanillaBackedRegistryImpl(net.minecraft.util.registry.Registry<T> delegate) {
|
||||||
|
this.delegate = delegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Supplier<T> delegate(ResourceLocation id) {
|
||||||
|
LazyValue<T> value = new LazyValue<>(() -> get(id));
|
||||||
|
return value::get;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Supplier<T> register(ResourceLocation id, Supplier<T> supplier) {
|
||||||
|
net.minecraft.util.registry.Registry.register(delegate, id, supplier.get());
|
||||||
|
return delegate(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public ResourceLocation getId(T obj) {
|
||||||
|
return delegate.getKey(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public T get(ResourceLocation id) {
|
||||||
|
return delegate.get(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ForgeBackedRegistryImpl<T extends IForgeRegistryEntry<T>> implements Registry<T> {
|
||||||
|
private IForgeRegistry<T> delegate;
|
||||||
|
private Table<Type, RegistryObject<?>, Supplier<? extends IForgeRegistryEntry<?>>> registry;
|
||||||
|
|
||||||
|
public ForgeBackedRegistryImpl(Table<Type, RegistryObject<?>, Supplier<? extends IForgeRegistryEntry<?>>> registry, IForgeRegistry<T> delegate) {
|
||||||
|
this.registry = registry;
|
||||||
|
this.delegate = delegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Supplier<T> delegate(ResourceLocation id) {
|
||||||
|
LazyValue<T> value = new LazyValue<>(() -> get(id));
|
||||||
|
return value::get;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Supplier<T> register(ResourceLocation id, Supplier<T> supplier) {
|
||||||
|
RegistryObject registryObject = RegistryObject.of(id, delegate);
|
||||||
|
registry.put(delegate.getRegistrySuperType(), registryObject, () -> supplier.get().setRegistryName(id));
|
||||||
|
return registryObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public ResourceLocation getId(T obj) {
|
||||||
|
return delegate.getKey(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public T get(ResourceLocation id) {
|
||||||
|
return delegate.getValue(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package me.shedaniel.architectury.utils.forge;
|
||||||
|
|
||||||
|
import me.shedaniel.architectury.utils.GameInstance;
|
||||||
|
import net.minecraft.server.MinecraftServer;
|
||||||
|
import net.minecraftforge.fml.server.ServerLifecycleHooks;
|
||||||
|
|
||||||
|
public class GameInstanceImpl implements GameInstance.Impl {
|
||||||
|
@Override
|
||||||
|
public MinecraftServer getServer() {
|
||||||
|
return ServerLifecycleHooks.getCurrentServer();
|
||||||
|
}
|
||||||
|
}
|
||||||
11
gradle.properties
Normal file
11
gradle.properties
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
minecraft_version=1.16.3
|
||||||
|
|
||||||
|
archives_base_name=architectury
|
||||||
|
mod_version=1.0.0
|
||||||
|
maven_group=me.shedaniel
|
||||||
|
|
||||||
|
fabric_loader_version=0.10.5+build.213
|
||||||
|
fabric_api_version=0.24.3+build.414-1.16
|
||||||
|
mod_menu_version=1.14.6+
|
||||||
|
|
||||||
|
forge_version=34.1.34
|
||||||
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
5
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
5
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
distributionBase=GRADLE_USER_HOME
|
||||||
|
distributionPath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-5.5.1-bin.zip
|
||||||
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
zipStorePath=wrapper/dists
|
||||||
185
gradlew
vendored
Executable file
185
gradlew
vendored
Executable file
@@ -0,0 +1,185 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright 2015 the original author or authors.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
##
|
||||||
|
## Gradle start up script for UN*X
|
||||||
|
##
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
# Attempt to set APP_HOME
|
||||||
|
# Resolve links: $0 may be a link
|
||||||
|
PRG="$0"
|
||||||
|
# Need this for relative symlinks.
|
||||||
|
while [ -h "$PRG" ] ; do
|
||||||
|
ls=`ls -ld "$PRG"`
|
||||||
|
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||||
|
if expr "$link" : '/.*' > /dev/null; then
|
||||||
|
PRG="$link"
|
||||||
|
else
|
||||||
|
PRG=`dirname "$PRG"`"/$link"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
SAVED="`pwd`"
|
||||||
|
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||||
|
APP_HOME="`pwd -P`"
|
||||||
|
cd "$SAVED" >/dev/null
|
||||||
|
|
||||||
|
APP_NAME="Gradle"
|
||||||
|
APP_BASE_NAME=`basename "$0"`
|
||||||
|
|
||||||
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||||
|
|
||||||
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
|
MAX_FD="maximum"
|
||||||
|
|
||||||
|
warn () {
|
||||||
|
echo "$*"
|
||||||
|
}
|
||||||
|
|
||||||
|
die () {
|
||||||
|
echo
|
||||||
|
echo "$*"
|
||||||
|
echo
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# OS specific support (must be 'true' or 'false').
|
||||||
|
cygwin=false
|
||||||
|
msys=false
|
||||||
|
darwin=false
|
||||||
|
nonstop=false
|
||||||
|
case "`uname`" in
|
||||||
|
CYGWIN* )
|
||||||
|
cygwin=true
|
||||||
|
;;
|
||||||
|
Darwin* )
|
||||||
|
darwin=true
|
||||||
|
;;
|
||||||
|
MINGW* )
|
||||||
|
msys=true
|
||||||
|
;;
|
||||||
|
NONSTOP* )
|
||||||
|
nonstop=true
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||||
|
|
||||||
|
|
||||||
|
# Determine the Java command to use to start the JVM.
|
||||||
|
if [ -n "$JAVA_HOME" ] ; then
|
||||||
|
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||||
|
# IBM's JDK on AIX uses strange locations for the executables
|
||||||
|
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||||
|
else
|
||||||
|
JAVACMD="$JAVA_HOME/bin/java"
|
||||||
|
fi
|
||||||
|
if [ ! -x "$JAVACMD" ] ; then
|
||||||
|
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
JAVACMD="java"
|
||||||
|
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Increase the maximum file descriptors if we can.
|
||||||
|
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||||
|
MAX_FD_LIMIT=`ulimit -H -n`
|
||||||
|
if [ $? -eq 0 ] ; then
|
||||||
|
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||||
|
MAX_FD="$MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
ulimit -n $MAX_FD
|
||||||
|
if [ $? -ne 0 ] ; then
|
||||||
|
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Darwin, add options to specify how the application appears in the dock
|
||||||
|
if $darwin; then
|
||||||
|
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||||
|
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||||
|
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||||
|
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||||
|
|
||||||
|
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||||
|
|
||||||
|
# We build the pattern for arguments to be converted via cygpath
|
||||||
|
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||||
|
SEP=""
|
||||||
|
for dir in $ROOTDIRSRAW ; do
|
||||||
|
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||||
|
SEP="|"
|
||||||
|
done
|
||||||
|
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||||
|
# Add a user-defined pattern to the cygpath arguments
|
||||||
|
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||||
|
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||||
|
fi
|
||||||
|
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||||
|
i=0
|
||||||
|
for arg in "$@" ; do
|
||||||
|
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||||
|
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||||
|
|
||||||
|
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||||
|
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||||
|
else
|
||||||
|
eval `echo args$i`="\"$arg\""
|
||||||
|
fi
|
||||||
|
i=`expr $i + 1`
|
||||||
|
done
|
||||||
|
case $i in
|
||||||
|
0) set -- ;;
|
||||||
|
1) set -- "$args0" ;;
|
||||||
|
2) set -- "$args0" "$args1" ;;
|
||||||
|
3) set -- "$args0" "$args1" "$args2" ;;
|
||||||
|
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||||
|
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||||
|
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||||
|
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||||
|
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||||
|
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Escape application args
|
||||||
|
save () {
|
||||||
|
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||||
|
echo " "
|
||||||
|
}
|
||||||
|
APP_ARGS=`save "$@"`
|
||||||
|
|
||||||
|
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||||
|
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||||
|
|
||||||
|
exec "$JAVACMD" "$@"
|
||||||
89
gradlew.bat
vendored
Normal file
89
gradlew.bat
vendored
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
@rem
|
||||||
|
@rem Copyright 2015 the original author or authors.
|
||||||
|
@rem
|
||||||
|
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@rem you may not use this file except in compliance with the License.
|
||||||
|
@rem You may obtain a copy of the License at
|
||||||
|
@rem
|
||||||
|
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
@rem
|
||||||
|
@rem Unless required by applicable law or agreed to in writing, software
|
||||||
|
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@rem See the License for the specific language governing permissions and
|
||||||
|
@rem limitations under the License.
|
||||||
|
@rem
|
||||||
|
|
||||||
|
@if "%DEBUG%" == "" @echo off
|
||||||
|
@rem ##########################################################################
|
||||||
|
@rem
|
||||||
|
@rem Gradle startup script for Windows
|
||||||
|
@rem
|
||||||
|
@rem ##########################################################################
|
||||||
|
|
||||||
|
@rem Set local scope for the variables with windows NT shell
|
||||||
|
if "%OS%"=="Windows_NT" setlocal
|
||||||
|
|
||||||
|
set DIRNAME=%~dp0
|
||||||
|
if "%DIRNAME%" == "" set DIRNAME=.
|
||||||
|
set APP_BASE_NAME=%~n0
|
||||||
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
|
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||||
|
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||||
|
|
||||||
|
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||||
|
|
||||||
|
@rem Find java.exe
|
||||||
|
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||||
|
|
||||||
|
set JAVA_EXE=java.exe
|
||||||
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
|
if "%ERRORLEVEL%" == "0" goto execute
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:findJavaFromJavaHome
|
||||||
|
set JAVA_HOME=%JAVA_HOME:"=%
|
||||||
|
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||||
|
|
||||||
|
if exist "%JAVA_EXE%" goto execute
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:execute
|
||||||
|
@rem Setup the command line
|
||||||
|
|
||||||
|
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||||
|
|
||||||
|
|
||||||
|
@rem Execute Gradle
|
||||||
|
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||||
|
|
||||||
|
:end
|
||||||
|
@rem End local scope for the variables with windows NT shell
|
||||||
|
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||||
|
|
||||||
|
:fail
|
||||||
|
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||||
|
rem the _cmd.exe /c_ return code!
|
||||||
|
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||||
|
exit /b 1
|
||||||
|
|
||||||
|
:mainEnd
|
||||||
|
if "%OS%"=="Windows_NT" endlocal
|
||||||
|
|
||||||
|
:omega
|
||||||
0
logs/latest.log
Normal file
0
logs/latest.log
Normal file
14
settings.gradle
Normal file
14
settings.gradle
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
pluginManagement {
|
||||||
|
repositories {
|
||||||
|
jcenter()
|
||||||
|
maven { url "https://maven.fabricmc.net/" }
|
||||||
|
maven { url "https://dl.bintray.com/shedaniel/cloth" }
|
||||||
|
gradlePluginPortal()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
include("common")
|
||||||
|
include("fabric")
|
||||||
|
include("forge")
|
||||||
|
|
||||||
|
rootProject.name = "architectury"
|
||||||
Reference in New Issue
Block a user