Compare commits
9 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
04e8e3b68d | ||
![]() |
2e1f9e8fb3 | ||
![]() |
0231f77fe4 | ||
![]() |
428b80afc6 | ||
![]() |
ba94674c6a | ||
![]() |
64a9cb2163 | ||
![]() |
044d551e70 | ||
![]() |
3d46f68aee | ||
![]() |
fdb046cdce |
103
.github/workflows/build.yml
vendored
Normal file
@ -0,0 +1,103 @@
|
||||
name: Build
|
||||
on: [push, pull_request, workflow_dispatch]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
permissions:
|
||||
contents: write
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
- name: Setup Java
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '21'
|
||||
cache: 'gradle'
|
||||
- name: Validate Gradle Wrapper
|
||||
uses: gradle/actions/wrapper-validation@v4
|
||||
- name: Compile client
|
||||
run: |
|
||||
bash ./CompileEPK.sh &&
|
||||
bash ./CompileJS.sh &&
|
||||
bash ./MakeOfflineDownload.sh
|
||||
- name: Compile client (WASM)
|
||||
run: |
|
||||
cd ./wasm_gc_teavm &&
|
||||
bash ./CompileEPK.sh &&
|
||||
bash ./CompileWASM.sh &&
|
||||
bash ./CompileEagRuntimeJS.sh &&
|
||||
bash ./CompileBootstrapJS.sh &&
|
||||
bash ./CompileLoaderWASM.sh &&
|
||||
bash ./MakeWASMClientBundle.sh &&
|
||||
cd ..
|
||||
- name: Prepare files
|
||||
run: |
|
||||
mkdir -p ${{ runner.temp }}/gh-pages &&
|
||||
cp -t ${{ runner.temp }}/gh-pages \
|
||||
./LICENSE.md \
|
||||
./javascript/assets.epk \
|
||||
./javascript/assets.epw \
|
||||
./javascript/bootstrap.js \
|
||||
./javascript/classes.js \
|
||||
./javascript/classes.js.map \
|
||||
./javascript/index.html \
|
||||
./javascript/Starlike_Client_Offline.html \
|
||||
./javascript/Starlike_Client_Offline_WASM.html \
|
||||
./javascript/wasm.html
|
||||
- name: Upload web files
|
||||
continue-on-error: true
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Starlike_Client_Web
|
||||
path: ${{ runner.temp }}/gh-pages
|
||||
retention-days: 1
|
||||
compression-level: 9
|
||||
- name: Upload offline download
|
||||
continue-on-error: true
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Starlike_Client_Offline
|
||||
path: |
|
||||
${{ runner.temp }}/gh-pages/LICENSE.md
|
||||
${{ runner.temp }}/gh-pages/Starlike_Client_Offline.html
|
||||
${{ runner.temp }}/gh-pages/Starlike_Client_Offline_WASM.html
|
||||
retention-days: 1
|
||||
compression-level: 9
|
||||
- name: Upload web files (WASM)
|
||||
continue-on-error: true
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Starlike_Client_Web_WASM
|
||||
path: |
|
||||
${{ runner.temp }}/gh-pages/LICENSE.md
|
||||
${{ runner.temp }}/gh-pages/assets.epw
|
||||
${{ runner.temp }}/gh-pages/bootstrap.js
|
||||
${{ runner.temp }}/gh-pages/Starlike_Client_Offline_WASM.html
|
||||
${{ runner.temp }}/gh-pages/wasm.html
|
||||
retention-days: 1
|
||||
compression-level: 9
|
||||
- name: Upload offline download (WASM)
|
||||
continue-on-error: true
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Starlike_Client_Offline_WASM
|
||||
path: |
|
||||
${{ runner.temp }}/gh-pages/LICENSE.md
|
||||
${{ runner.temp }}/gh-pages/Starlike_Client_Offline_WASM.html
|
||||
retention-days: 1
|
||||
compression-level: 9
|
||||
- name: Deploy to `gh-pages` branch
|
||||
if: github.ref == 'refs/heads/main'
|
||||
uses: peaceiris/actions-gh-pages@v4
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
publish_dir: ${{ runner.temp }}/gh-pages
|
||||
allow_empty_commit: true
|
||||
force_orphan: true
|
||||
user_name: 'github-actions[bot]'
|
||||
user_email: '41898282+github-actions[bot]@users.noreply.github.com'
|
||||
commit_message: 'github-actions: deploy'
|
||||
# disable_nojekyll: true
|
||||
cname: 'starlike.zumbiepig.dev'
|
12
.gitignore
vendored
@ -15,7 +15,19 @@ desktopRuntime/_eagstorage*
|
||||
desktopRuntime/filesystem/*
|
||||
desktopRuntime/downloads/*
|
||||
desktopRuntime/screenshots/*
|
||||
|
||||
javascript/assets.epk
|
||||
javascript/classes.js
|
||||
javascript/classes.js.map
|
||||
javascript/Starlike_Client_Offline.html
|
||||
javascript/Starlike_Client_Offline_Signed.html
|
||||
javascript/Starlike_Client_Offline_Signed.html.cert
|
||||
javascript/Starlike_Client_Offline_Signed.html.dat
|
||||
|
||||
javascript/assets.epw
|
||||
javascript/bootstrap.js
|
||||
javascript/favicon.png
|
||||
javascript/Starlike_Client_Offline_WASM.html
|
||||
|
||||
.metadata
|
||||
.DS_Store
|
||||
|
@ -1,306 +0,0 @@
|
||||
# Eaglercraft Code Standards
|
||||
|
||||
**These are some basic rules to follow if you would like to write code that is consistent with the Eaglercraft 1.8 codebase. If you are already familiar with Eaglercraft 1.5 or b1.3, please abandon whatever you think is the best practice as a result of reading that code, those clients should be considered as obsolete prototypes.**
|
||||
|
||||
## Part A. Coding Style
|
||||
|
||||
### 1. Tabs, not spaces
|
||||
|
||||
Tabs not spaces, it makes indentation easier to manage and reduces file size. Other popular projects that are also known to use tabs instead of spaces include the linux kernel. We prefer to set tab width to 4 spaces on our editors.
|
||||
|
||||
Format code like the eclipse formatter on factory settings
|
||||
|
||||
### 2. Avoid redundant hash map lookups
|
||||
|
||||
Don't retrieve the same value from a hash map more than once, that includes checking if an entry exists first before retrieving its value. If you do this, you are a horrible person!
|
||||
|
||||
**Incorrect:**
|
||||
|
||||
```java
|
||||
if(hashMap.containsKey("eagler")) {
|
||||
Object val = hashMap.get("eagler");
|
||||
// do something with val
|
||||
}
|
||||
```
|
||||
|
||||
**Correct:**
|
||||
|
||||
```java
|
||||
Object val = hashMap.get("eagler");
|
||||
if(val != null) {
|
||||
// do something with val
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Cache the return value of a function if you plan to use it multiple times
|
||||
|
||||
This is somewhat an extension of rule #2, don't repeatedly call the same function multiple times if there's no reason to, even if its a relatively fast function. Everything is slower and less efficient in a browser.
|
||||
|
||||
**Incorrect:**
|
||||
|
||||
```java
|
||||
while(itr.hasNext()) {
|
||||
if(!Minecraft.getMinecraft().getRenderManager().getEntityClassRenderObject(SomeEntity.class).shouldRender(itr.next())) {
|
||||
itr.remove();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Correct:**
|
||||
|
||||
```java
|
||||
Render<SomeEntity> render = Minecraft.getMinecraft().getRenderManager().getEntityClassRenderObject(SomeEntity.class);
|
||||
while(itr.hasNext()) {
|
||||
if(!render.shouldRender(itr.next())) {
|
||||
itr.remove();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Iterators aren't that great
|
||||
|
||||
Avoid using iterators when possible, this includes a `for(Item item : list)` type loop, since this may compile into bytecode that uses an iterator. If the list is a linked list or some other type of data structure that can’t perform random access efficiently, then it is recommended to use an iterator, but if the collection is guaranteed to be something similar to an ArrayList then implement it via a traditional for loop instead.
|
||||
|
||||
**Recommended way to iterate an ArrayList:**
|
||||
|
||||
```java
|
||||
for(int i = 0, l = list.size(); i < l; ++i) {
|
||||
Item item = list.get(i);
|
||||
// do something
|
||||
}
|
||||
```
|
||||
|
||||
### 5. Don't shit on the heap
|
||||
|
||||
Avoid creating temporary single-use objects in performance critical code, since the overhead of doing so is larger in a browser where there’s no type safety to predefine object structures. This includes using lambdas or using most of the stuff in the google guava package. Also this is partially why I prefer not using iterators whenever possible.
|
||||
|
||||
**Incorrect, creates 5 temporary objects:**
|
||||
|
||||
```java
|
||||
List<String> list1 = Arrays.asList("eagler", "eagler", "deevis");
|
||||
List<String> list2 = Lists.newArrayList(
|
||||
Collections2.transform(
|
||||
Collections2.filter(
|
||||
list1,
|
||||
(e) -> !e.equals("deevis")
|
||||
),
|
||||
(e) -> (e + "!")
|
||||
)
|
||||
);
|
||||
```
|
||||
|
||||
**Correct, creates no temporary objects:**
|
||||
|
||||
```java
|
||||
List<String> list1 = Arrays.asList("eagler", "eagler", "deevis");
|
||||
List<String> list2 = Lists.newArrayList();
|
||||
for(int i = 0, l = list1.size(); i < l; ++i) {
|
||||
String s = list1.get(i);
|
||||
if(!s.equals("deevis")) {
|
||||
list2.add(s + "!");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
(note: we are ignoring the StringBuilder instances that the compiler generates from ` + "!"`)
|
||||
|
||||
### 6. Don't base game/render logic off of the system time
|
||||
|
||||
Use `EagRuntime.steadyTimeMillis()` instead to access a monotonic clock, as in a clock that is guaranteed to only run forwards, and is not affected by changes in the system time. `System.currentTimeMillis()` should only be used in situations where you want to know the actual wall time or are measuring elapsed time across multiple page refreshes.
|
||||
|
||||
### 7. Prefer multiplication over division
|
||||
|
||||
If you're always gonna divide a number by some constant, it is better to multiply it by one-over-the-constant instead.
|
||||
|
||||
**Incorrect**
|
||||
|
||||
```java
|
||||
float b = a / 50.0f;
|
||||
```
|
||||
|
||||
**Correct**
|
||||
|
||||
```java
|
||||
float b = a * 0.02f;
|
||||
```
|
||||
|
||||
### 8. Shaders should take advantage of compiler intrinsics
|
||||
|
||||
Although you may think these two pieces of code are identical, its more than likely that the "Correct" example will compile to a more efficient shader on almost any hardware. The functions in GLSL are not a library, they are compiler intrinsics that usually compile to inline assembly that can take advantage of different acceleration instructions in the GPU's instruction set. Vector math should be done in ways that promotes the use of SIMD instructions when the code is compiled to a shader.
|
||||
|
||||
**Incorrect:**
|
||||
|
||||
```glsl
|
||||
float dx = pos1.x - pos2.x;
|
||||
float dy = pos1.y - pos2.y;
|
||||
float dz = pos1.z - pos2.z;
|
||||
float distance = sqrt(dx * dx + dy * dy + dz * dz);
|
||||
float fogDensity = pow(2.718, -density * distance);
|
||||
```
|
||||
|
||||
**Correct:**
|
||||
|
||||
```glsl
|
||||
float fogDensity = exp(-density * length(pos1.xyz - pos2.xyz));
|
||||
```
|
||||
|
||||
### 9. Flatten the control flow of shaders
|
||||
|
||||
Modern GPUs are able to execute multiple instances of a shader on a single core, but if one of those shaders encounters a branch (if statement, or related) that causes it to begin executing different code from the other instances of the shader running on that core, that instance of the shader can no longer be executed at the same time as the other instances, and suddenly you've significantly increased the amount of time this core will now be busy executing shader instructions to account for all of the branches the different shader instances have taken.
|
||||
|
||||
**Incorrect:**
|
||||
|
||||
```glsl
|
||||
float lightValue = dot(lightDirection, normal);
|
||||
if(lightValue > 0.0) {
|
||||
color += lightValue * lightColor * diffuseColor;
|
||||
}
|
||||
```
|
||||
|
||||
**Correct:**
|
||||
```glsl
|
||||
float lightValue = max(dot(lightDirection, normal), 0.0);
|
||||
color += lightValue * lightColor * diffuseColor;
|
||||
```
|
||||
|
||||
### 10. Use textureLod unless mipmapping is necessary
|
||||
|
||||
This will prevent the shader from wasting time trying to determine what mipmap levels to read from when the texture is sampled.
|
||||
|
||||
**Incorrect:**
|
||||
|
||||
```glsl
|
||||
float depthValue = texture(depthBuffer, pos).r;
|
||||
```
|
||||
|
||||
**Correct:**
|
||||
|
||||
```glsl
|
||||
float depthValue = textureLod(depthBuffer, pos, 0.0).r;
|
||||
```
|
||||
|
||||
### 11. Divide complex and branch-intensive shaders into multiple draw calls
|
||||
|
||||
You can use a variety of different blending modes to mathematically combine the results of shaders. This is done for the same reason as flattening the control flow, to try and keep instruction pointers in sync by periodically resetting their positions, and also to allow for the driver to multitask better on GPUs with insane numbers of cores. It also allows the shader’s execution to be distributed across multiple frames in the case of something that doesn’t need to update often (like clouds).
|
||||
|
||||
|
||||
### 12. Don't abuse `@JSBody` in TeaVM code
|
||||
|
||||
TeaVM provides lots of ways of interacting with JavaScript, using `@JSBody` is not the only way, consider using an overlay type.
|
||||
|
||||
**Incorrect**
|
||||
|
||||
```java
|
||||
@JSObject(params = { "obj" }, script = "return obj.valueA;")
|
||||
public static native JSObject getValueA(JSObject obj);
|
||||
|
||||
@JSObject(params = { "obj" }, script = "return obj.valueB;")
|
||||
public static native JSObject getValueB(JSObject obj);
|
||||
|
||||
@JSObject(params = { "obj" }, script = "return obj.valueC;")
|
||||
public static native JSObject getValueC(JSObject obj);
|
||||
|
||||
@JSObject(params = { "obj" }, script = "obj.dumbFunction();")
|
||||
public static native void callDumbFunction(JSObject obj);
|
||||
```
|
||||
|
||||
**Correct**
|
||||
|
||||
```java
|
||||
public interface MyObject extends JSObject {
|
||||
|
||||
@JSProperty
|
||||
JSObject getValueA();
|
||||
|
||||
@JSProperty
|
||||
JSObject getValueB();
|
||||
|
||||
@JSProperty
|
||||
JSObject getValueC();
|
||||
|
||||
void dumbFunction();
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
### 13. Don't fall for TeaVM's threads
|
||||
|
||||
It is impossible to have multithreading in JavaScript, only worker objects can be used to execute code concurrently, which can't share javascript variables. Therefore, when you create a thread in TeaVM, you're creating a virtual thread that isn't capable of running at the same time as any other virtual thread in the TeaVM context. This means it's impossible to speed a TeaVM program up through the use of multiple Java threads, instead it is more than likely that it will just slow the program down more to implement multithreading through TeaVM's threads due to the additional time required for synchronization and context switches. Its more efficient to just program the entire application to be single threaded to begin with, just put everything in the main loop and realize that if it was in a different thread it would just periodically interrupt the main loop.
|
||||
|
||||
### 14. Always use try-with-resources
|
||||
|
||||
For any code that deals with streams to be considered safe, it should either use a try-with-resources or try/finally in order to release resources when complete, since otherwise the stream might not close if an IO error causes the function to return early. This is especially important for plugin code since its supposed to be able to run on a large server for weeks at a time without the underlying JVM being restarted. If hackers discover a bug in the code to cause a function to return early like this without closing a stream, they might exploit it to fatally crash the server by spamming whatever corrupt packet causes the function to leak the stream, so all code must be written so it can fail at any time without leaking resources.
|
||||
|
||||
**Incorrect**
|
||||
|
||||
```java
|
||||
InputStream is = new FileInputStream(new File("phile.txt"));
|
||||
is.write(someArray);
|
||||
is.close();
|
||||
```
|
||||
|
||||
**Correct**
|
||||
|
||||
```java
|
||||
try(InputStream is = new FileInputStream(new File("phile.txt"))) {
|
||||
is.write(someArray);
|
||||
}
|
||||
```
|
||||
|
||||
Notice that the `.close()` can be omitted completely when using a try-with-resources
|
||||
|
||||
### 15. Always close compression/decompression streams
|
||||
|
||||
In the desktop runtime, the default oracle JDK uses native code to implement the compression/decompression streams (InflaterInputStream, GZIPInputStream, etc) and therefore if you forget to close the compression/decompression stream it will cause a memory leak when the code isn't running in a browser. This is a common issue when using byte array input/output streams since you might believe when decompressing data from a byte array that there's no reason to close the stream when you're done since its not a file, but that will still cause a memory leak due to the decompression stream not being cleaned up.
|
||||
|
||||
## Part B. Project Structure
|
||||
|
||||
### 1. Code decompiled from Minecraft goes in `src/game/java`
|
||||
|
||||
Don't add any new classes to `src/game/java`, and ideally any significant additions to the game's source (functions, etc) should be done through creating new classes in `src/main/java` instead of adding it directly to the decompiled classes.
|
||||
|
||||
### 2. Do not put platform-dependent code in `src/main/java` or `src/game/java`
|
||||
|
||||
One of the objectives of Eaglercraft is to make Minecraft Java edition truly cross platform, why stop at just a desktop and JavaScript runtime? There are plans to create an Android runtime and several WebAssembly runtimes, all of which will be compatible with any pre-existing eaglercraft clients that only depend on the EaglercraftX runtime library and don't directly depend on components of TeaVM or LWJGL. Ideally, all core features of the client should be implemented in the `src/main/java` and `src/game/java` and any platform-dependent features should be stubbed out in some abstract platform-independent way in classes in the `src/teavm/java` and `src/lwjgl/java` and any other future runtime you want your client to support. Ideally, every source folder of platform-dependent code should expose an identical API for access to the platform-independent code as all the other platform-dependant code folders currently expose.
|
||||
|
||||
### 3. Don't mix JavaScript with Java
|
||||
|
||||
Don’t implement features in the JavaScript runtime by requiring additional JavaScript files be included on index.html, if you must access browser APIs then use the TeaVM JSO to write your code in Java instead so it’s baked directly into classes.js. Certain browser APIs may be missing from the default TeaVM JSO-APIs library but it is not difficult to create the overlay types for them manually. Clients that violate this rule may also not possible to automatically import into the EaglercraftX boot menu depending on how fucked up they are. There aren't any limitations to the TeaVM JSO that give you a good enough excuse not to follow this rule.
|
||||
|
||||
### 4. Don't access the classes named "Platform\*" directly from your platform-independent code
|
||||
|
||||
Much like the Java runtime environment itself, Eaglercraft's runtime library consists of two layers, the internal classes full of platform-dependent code that expose an intermediate API not meant to be used by programmers directly, and the platform-independent API classes that provide a platform-independent wrapper for the platform dependent classes and also provide all the miscellaneous utility functions that don't require platform dependent code to be implemented. Chances are if you are directly using a function on a class that has a name that starts with "Platform\*", that there is a different class in `src/main/java` that you are meant to use in order to access that feature, that may perform additional checks or adjust the values you are passing to the function before calling the function in the Platform class.
|
||||
|
||||
## Part C. Compatibility Standards
|
||||
|
||||
### 1. Target minimum JDK version is Java 8
|
||||
|
||||
Its difficult to find a platform where its not possible to run Java 8 in some capacity, therefore the desktop runtime of EaglercraftX and the BungeeCord plugin should target Java 8. The Velocity plugin is an exception since Velocity itself doesn't support Java 8 either.
|
||||
|
||||
### 2. Target minimum supported browser is Google Chrome 38
|
||||
|
||||
Released on October 7, 2014, we think its a good target for the JavaScript versions of EaglercraftX. This is the last version of Chrome that supports hardware accelerated WebGL 1.0 on Windows XP. All base features of the underlying Minecraft 1.8 client must be functional, however things such as EaglercraftX's shaders or dynamic lighting are not required to work. The client cannot crash as a result of any missing features on an old browser, you must either implement fallbacks or safely disable the unsupported features.
|
||||
|
||||
### 3. Target minimum supported graphics API is OpenGL ES 2.0 (WebGL 1.0)
|
||||
|
||||
The most widely supported graphics API in the world is currently OpenGL ES 2.0, so ideally that should be the target for EaglercraftX 1.8. We can guarantee the client will be on an OpenGL ES 3.0 context 99% of the time, however its not that hard to also maintain support for GLES 2.0 (WebGL 1.0) as well with slightly reduced functionality so we might as well make it a feature in case of the 1% of the time that functionality is not available. The client cannot depend on any GL extensions in order to run in GLES 2.0 mode, however its reasonable to assume there will be VAO support via extensions in most GLES 2.0 contexts so the client includes an abstraction layer (via EaglercraftGPU.java) to seamlessly emulate VAO functionality even when the client is running in GLES 2.0 mode with no VAO extensions. The only core feature of Minecraft 1.8 that is completely unavailable in GLES 2.0 mode is mip-mapping for the blocks/items texture atlas due to being unable to limit the max mipmap level.
|
||||
|
||||
### 4. Use preprocessor directives to make portable shaders that can be compiled for both OpenGL ES 2.0 and 3.0 contexts
|
||||
|
||||
Most of the shaders in the base "glsl" directory of the resources EPK file use a file called "gles2_compat.glsl" to polyfill certain GLSL features (such as input/output declarations) via preprocessor directives to allow them to be compiled on both OpenGL ES 3.0 and 2.0 contexts. This is the preferred way to implement backwards compatibility over creating seprate versions of the same shaders, since future developers don't need to waste time maintaining multiple versions of the same code if they don't really care about backwards compatibility in the first place.
|
||||
|
||||
### 5. Target minimum version of the JavaScript syntax is ES5 strict mode
|
||||
|
||||
A shim is included to provide certain ES6 functions, however you should always program with syntax compatible with ES5, so the script doesn't crash immediately due to syntax errors even if the functions that use unsupported syntax aren't actually being called. `build.gradle` currently patches out all the ES5 strict mode incompatible syntax in the output of TeaVM 0.9.2, but this will probably break if you try to update TeaVM. Don't worry though because future WASM versions of EaglercraftX will use the latest versions of TeaVM. **Some common incompatible syntax to avoid includes `const`, `let`, `async`, `( ) => `, and using named functions! You can't do any of these things in your JSBody annotations.**
|
||||
|
||||
### 6. You cannot depend on any deprecated browser features
|
||||
|
||||
The same way we want EaglercraftX to work on browsers from over 10 years ago, we want it to still work in browsers 10 years from today, therefore the client cannot depend on any deprecated browser features in order for all the base Minecraft 1.8 game's features to work properly. However it is okay to use deprecated features as fallback if any modern non-deprecated feature (such as keyboard event handling) that the game needs if the game is running in an old browser.
|
||||
|
||||
### 7. Always use addEventListener to register event handlers
|
||||
|
||||
Always use addEventListener to register event handlers for browser APIs, never through the use of assigning the legacy "on\*" (onclick, onkeydown, onmessage, etc) variables, the TeaVMUtils class has a universal helper function for accessing addEventListener on any JSO objects that don’t already implement the function.
|
||||
|
||||
### 8. JavaScript should be executed in strict mode
|
||||
|
||||
Always make sure your JavaScript files start with `"use strict";`, be careful when adding this to your code retroactively because it will probably break hastily written code unless you haven’t made a single typo that’s not forbidden in strict mode. Be aware that in Chrome 38 this means you can't use stuff such as `const` and `let` or named functions in any of your JSBody annotations!
|
@ -3,4 +3,4 @@ title epkcompiler
|
||||
echo compiling, please wait...
|
||||
java -jar "desktopRuntime/CompileEPK.jar" "desktopRuntime/resources" "javascript/assets.epk"
|
||||
echo finished compiling epk
|
||||
pause
|
||||
pause
|
||||
|
4
CompileEPK.sh
Normal file → Executable file
@ -1,2 +1,4 @@
|
||||
#!/bin/sh
|
||||
java -jar "desktopRuntime/CompileEPK.jar" "desktopRuntime/resources" "javascript/assets.epk"
|
||||
echo "compiling, please wait..."
|
||||
java -jar "desktopRuntime/CompileEPK.jar" "desktopRuntime/resources" "javascript/assets.epk"
|
||||
echo "finished compiling epk"
|
||||
|
11
CompileFull.bat
Normal file
@ -0,0 +1,11 @@
|
||||
call CompileEPK &&
|
||||
call CompileJS &&
|
||||
call MakeOfflineDownload &&
|
||||
cd wasm_gc_teavm &&
|
||||
call CompileEPK &&
|
||||
call CompileWASM &&
|
||||
call CompileEagRuntimeJS &&
|
||||
call CompileBootstrapJS &&
|
||||
call CompileLoaderWASM &&
|
||||
call MakeWASMClientBundle &&
|
||||
cd ..
|
12
CompileFull.sh
Executable file
@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
. ./CompileEPK.sh &&
|
||||
. ./CompileJS.sh &&
|
||||
. ./MakeOfflineDownload.sh &&
|
||||
cd ./wasm_gc_teavm &&
|
||||
. ./CompileEPK.sh &&
|
||||
. ./CompileWASM.sh &&
|
||||
. ./CompileEagRuntimeJS.sh &&
|
||||
. ./CompileBootstrapJS.sh &&
|
||||
. ./CompileLoaderWASM.sh &&
|
||||
. ./MakeWASMClientBundle.sh &&
|
||||
cd ..
|
@ -1,4 +1,4 @@
|
||||
@echo off
|
||||
title gradlew generateJavascript
|
||||
gradlew generateJavascript
|
||||
call gradlew generateJavascript
|
||||
pause
|
||||
|
3
CompileJS.sh
Normal file → Executable file
@ -1,2 +1,3 @@
|
||||
#!/bin/sh
|
||||
./gradlew generateJavascript
|
||||
chmod +x gradlew
|
||||
./gradlew generateJavaScript
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
# EaglercraftX 1.8
|
||||
|
||||
### Play Minecraft 1.8 in your browser, supports singleplayer and multiplayer
|
||||
@ -7,28 +6,28 @@
|
||||
|
||||
### This repository contains:
|
||||
|
||||
- **Utilities to decompile Minecraft 1.8 and apply patch files to it**
|
||||
- **Source code to provide the LWJGL keyboard, mouse, and OpenGL APIs in a browser**
|
||||
- **Patch files to mod the Minecraft 1.8 source code to make it browser compatible**
|
||||
- **Browser-modified portions of Minecraft 1.8's open-source dependencies**
|
||||
- **Plugins for Minecraft servers to allow the eagler client to connect to them**
|
||||
- **Utilities to decompile Minecraft 1.8 and apply patch files to it**
|
||||
- **Source code to provide the LWJGL keyboard, mouse, and OpenGL APIs in a browser**
|
||||
- **Patch files to mod the Minecraft 1.8 source code to make it browser compatible**
|
||||
- **Browser-modified portions of Minecraft 1.8's open-source dependencies**
|
||||
- **Plugins for Minecraft servers to allow the eagler client to connect to them**
|
||||
|
||||
### This repository does NOT contain:
|
||||
|
||||
- **Any portion of the decompiled Minecraft 1.8 source code or resources**
|
||||
- **Any portion of Mod Coder Pack and it's config files**
|
||||
- **Data that can be used alone to reconstruct portions of the game's source code**
|
||||
- **Any portion of the decompiled Minecraft 1.8 source code or resources**
|
||||
- **Any portion of Mod Coder Pack and it's config files**
|
||||
- **Data that can be used alone to reconstruct portions of the game's source code**
|
||||
|
||||
## Getting Started:
|
||||
|
||||
### To compile the latest version of the client, on Windows:
|
||||
### To compile the latest version of the JavaScript client, on Windows:
|
||||
|
||||
1. Make sure you have at least Java 11 installed and added to your PATH, it is recommended to use Java 17
|
||||
2. Download (clone) this repository to your computer
|
||||
3. Double click `CompileLatestClient.bat`, a GUI resembling a classic windows installer should open
|
||||
4. Follow the steps shown to you in the new window to finish compiling
|
||||
|
||||
### To compile the latest version of the client, on Linux/macOS:
|
||||
### To compile the latest version of the JavaScript client, on Linux/macOS:
|
||||
|
||||
1. Make sure you have at least Java 11 installed, it is recommended to use Java 17
|
||||
2. Download (clone) this repository to your computer
|
||||
@ -37,9 +36,21 @@
|
||||
5. Type `./CompileLatestClient.sh` and hit enter, a GUI resembling a classic windows installer should open
|
||||
6. Follow the steps shown to you in the new window to finish compiling
|
||||
|
||||
### To set up the development environment
|
||||
|
||||
1. Prepare the required files in the mcp918 folder ([readme](mcp918/readme.txt))
|
||||
2. Run the `build_init` script
|
||||
3. Run the `build_make_workspace` script
|
||||
|
||||
## Browser Compatibility
|
||||
|
||||
EaglercraftX 1.8 is currently known to work on browsers as old as Chrome 38 on Windows XP, the game supports both WebGL 1.0 and WebGL 2.0 however features such as dynamic lighting and PBR shaders require WebGL 2.0. The game also supports mobile browsers that don't have a keyboard or mouse, the game will enter touch screen mode automatically when touch input is detected. The game also includes an embedded OGG codec (JOrbis) for loading audio files on iOS where the browsers don't support loading OGG files in an AudioContext.
|
||||
The JavaScript runtime of EaglercraftX 1.8 is currently known to work on browsers as old as Chrome 38 on Windows XP, the game supports both WebGL 1.0 and WebGL 2.0 however features such as dynamic lighting and PBR shaders require WebGL 2.0. The game also supports mobile browsers that don't have a keyboard or mouse, the game will enter touch screen mode automatically when touch input is detected. The game also includes an embedded OGG codec (JOrbis) for loading audio files on iOS where the browsers don't support loading OGG files in an AudioContext.
|
||||
|
||||
## WebAssembly GC Support
|
||||
|
||||
EaglercraftX 1.8 also has an experimental WebAssembly GC (WASM-GC) runtime, almost all of the features supported on the JavaScript runtime are also supported on the WebAssembly GC runtime, however it is still incompatible with several major browsers (especially Safari) and will not run in Chrome unless you can access the `chrome://flags` menu or request an origin trial token from Google for your website. Its based on experimental technology and may still crash sometimes due to browser bugs or unresolved issues in the Java to WASM compiler. Hopefully in the coming months the required feature (JSPI, WebAssembly JavaScript Promise Integration) will become enabled by default on the Chrome browser. It performs significantly better than the JavaScript client, around 50% more FPS and TPS in some cases, and will hopefully replace it someday. Just make sure you enable VSync when you play it, otherwise the game will run "too fast" and choke the browser's event loop, causing input lag.
|
||||
|
||||
You can compile the WebAssembly GC runtime by creating a development environment (workspace) and reading the README in the "wasm_gc_teavm" folder.
|
||||
|
||||
## Singleplayer
|
||||
|
||||
@ -55,7 +66,7 @@ If you would like to invite other players to join your singleplayer world and pl
|
||||
|
||||
Once you press "Start Shared World", EaglercraftX 1.8 will give you a "join code" (usually 5 letters) to share with your friends. On a different device, go the "Multiplayer" screen and press "Direct Connect" and press "Join Shared World", enter the join code given to you when you started the shared world and press "Join World". Given a few seconds, the client should successfully be able to join your shared world from any other device on the internet that also has unrestricted internet access. If it does not work, check the "Network Settings" screen and make sure you and your friends all have the same set of shared world relay URLs configured or your clients will not be able to find each other.
|
||||
|
||||
If you would like to host your own relay, the JAR file and instructions can be downloaded from the "Network Settings" screen in the client. EaglercraftX 1.8 uses the same "LAN world" relay server that is used by Eaglercraft 1.5.2, if you would like the relay source code find a random copy of the Eaglercraft 1.5.2 source code and it should be located in the "sp-relay" folder. The relay has not been updated since then, it has only been renamed from "LAN world relay" to "Shared world relay".
|
||||
If you would like to host your own relay, the JAR file and instructions can be downloaded from the "Network Settings" screen in the client. EaglercraftX 1.8 uses the same "LAN world" relay server that is used by Eaglercraft 1.5.2, however there have been several bug fixes. The current version is available in the `sp-relay/SharedWorldRelay` folder.
|
||||
|
||||
## PBR Shaders
|
||||
|
||||
@ -77,6 +88,8 @@ To make a server for EaglercraftX 1.8 the recommended software to use is Eaglerc
|
||||
|
||||
There is an experimental velocity plugin available in `gateway/EaglercraftXVelocity` but it is still in development and not recommended for public servers, so be sure to check for updates regularly if you use it. Configuration files are basically identical to EaglercraftXBungee so its safe to just directy copy in your old EaglercraftXBungee config files to the `plugins/eaglerxvelocity` folder and they should work with a minimal number of edits if you are migrating your network from BungeeCord to Velocity.
|
||||
|
||||
**Warning:** Both EaglerXBungee and EaglerXVelocity perform a lot of reflection that will inevitably break after a while when BungeeCord or Velocity is updated upstream. Both plugins will display the precise build number of BungeeCord and Velocity that has been tested by the developers and known to be compatible with EaglerXBungee and EaglerXVelocity when the proxy first starts up. If you are experiencing issues, try checking the BungeeCord or Velocity website for old versions and find the closest version number to whatever the current compatible version number is that is printed by EaglerXBungee/EaglerXVelocity, it will probably fix whatever missing functions the error messages are complaining about.
|
||||
|
||||
### Detailed READMEs
|
||||
|
||||
- [**EaglerXBungee README**](README_EAGLERXBUNGEE.md)
|
||||
@ -158,6 +171,7 @@ The default eaglercraftXOpts values is this:
|
||||
- `demoMode:` whether to launch the game in java edition demo mode
|
||||
- `servers:` a list of default servers to display on the Multiplayer screen
|
||||
- `relays:` the default list of shared world relays to use for invites
|
||||
- `checkGLErrors:` if the game should check for opengl errors
|
||||
- `checkShaderGLErrors:` enables more verbose opengl error logging for the shaders
|
||||
- `enableDownloadOfflineButton:` whether to show a "Download Offline" button on the title screen
|
||||
- `downloadOfflineButtonLink:` overrides the download link for the "Download Offline" button
|
||||
@ -196,11 +210,13 @@ The default eaglercraftXOpts values is this:
|
||||
- `eaglerNoDelay:` can be used to disable "Vigg's Algorithm", an algorithm that delays and combines multiple EaglercraftX packets together if they are sent in the same tick (does not affect regular Minecraft 1.8 packets)
|
||||
- `ramdiskMode:` if worlds and resource packs should be stored in RAM instead of IndexedDB
|
||||
- `singleThreadMode:` if the game should run the client and integrated server in the same context instead of creating a worker object
|
||||
- `enableEPKVersionCheck:` if the game should attempt to bypass the browser's cache and retry downloading assets.epk when its outdated
|
||||
- `enforceVSync:` (WASM only) if the game should automatically re-enable VSync at launch if its disabled
|
||||
- `hooks:` can be used to define JavaScript callbacks for certain events
|
||||
* `localStorageSaved:` JavaScript callback to save local storage keys (key, data)
|
||||
* `localStorageLoaded:` JavaScript callback to load local storage keys (key) returns data
|
||||
* `crashReportShow:` JavaScript callback when a crash report is shown (report, customMessageCB)
|
||||
* `screenChanged:` JavaScript callback when the screen changes/resizes (screenName, scaledWidth, scaledHeight, realWidth, realHeight, scaleFactor)
|
||||
- `localStorageSaved:` JavaScript callback to save local storage keys (key, data)
|
||||
- `localStorageLoaded:` JavaScript callback to load local storage keys (key) returns data
|
||||
- `crashReportShow:` JavaScript callback when a crash report is shown (report, customMessageCB)
|
||||
- `screenChanged:` JavaScript callback when the screen changes/resizes (screenName, scaledWidth, scaledHeight, realWidth, realHeight, scaleFactor)
|
||||
|
||||
### Using Hooks
|
||||
|
||||
@ -243,4 +259,344 @@ The `crashReportShow` hook can be used to capture crash reports and append addit
|
||||
|
||||
There is currently no system in place to make forks of 1.8 and merge commits made to the patch files in this repository with the patch files or workspace of the fork, you're on your own if you try to keep a fork of this repo for reasons other than to contribute to it
|
||||
|
||||
A javascript-based modding API resembling Minecraft Forge may be implemented someday though for adding custom content to the game.
|
||||
**Note:** If you are trying to use the desktop runtime on Linux, make sure you add the "desktopRuntime" folder to the `LD_LIBRARY_PATH` environment variable of the Java process. This should be done automatically by the Eclipse project's default run configuration, but it might not work properly on every system, or when the Eclipse project is imported into IntelliJ.
|
||||
|
||||
# EaglercraftX 1.8 Workspace
|
||||
|
||||
### Java 17 is recommended for compiling to TeaVM
|
||||
|
||||
### Java 8 or greater is required for the desktop runtime
|
||||
|
||||
**Most Java IDEs will allow you to import this repository as a gradle project for compiling it to JavaScript.**
|
||||
|
||||
Java must be added to your PATH!
|
||||
|
||||
**To compile the web client:**
|
||||
|
||||
1. Run `CompileEPK`
|
||||
2. Run `CompileJS` (or the `generateJavaScript` gradle task in your IDE)
|
||||
3. Check the "javascript" folder
|
||||
|
||||
**To compile an offline download:**
|
||||
|
||||
1. Run `CompileEPK`
|
||||
2. Run `CompileJS` (or the `generateJavaScript` gradle task in your IDE)
|
||||
3. Run `MakeOfflineDownload`
|
||||
4. Check the "javascript" folder
|
||||
|
||||
**To use the desktop runtime:**
|
||||
|
||||
1. Import the Eclipse project in "desktopRuntime/eclipseProject" into your IDE
|
||||
2. Open one of the .java files from the source folders (workaround for a bug)
|
||||
3. Run/Debug the client with the included "eaglercraftDebugRuntime" configuration
|
||||
|
||||
**See the main 1.8 repository's README for more info**
|
||||
|
||||
The source codes of EaglercraftXBungee and EaglercraftXVelocity are not included here.
|
||||
|
||||
# Eaglercraft Code Standards
|
||||
|
||||
**These are some basic rules to follow if you would like to write code that is consistent with the Eaglercraft 1.8 codebase. If you are already familiar with Eaglercraft 1.5 or b1.3, please abandon whatever you think is the best practice as a result of reading that code, those clients should be considered as obsolete prototypes.**
|
||||
|
||||
## Part A. Coding Style
|
||||
|
||||
### 1. Tabs, not spaces
|
||||
|
||||
Tabs not spaces, it makes indentation easier to manage and reduces file size. Other popular projects that are also known to use tabs instead of spaces include the linux kernel. We prefer to set tab width to 4 spaces on our editors.
|
||||
|
||||
Format code like the eclipse formatter on factory settings
|
||||
|
||||
### 2. Avoid redundant hash map lookups
|
||||
|
||||
Don't retrieve the same value from a hash map more than once, that includes checking if an entry exists first before retrieving its value. If you do this, you are a horrible person!
|
||||
|
||||
**Incorrect:**
|
||||
|
||||
```java
|
||||
if(hashMap.containsKey("eagler")) {
|
||||
Object val = hashMap.get("eagler");
|
||||
// do something with val
|
||||
}
|
||||
```
|
||||
|
||||
**Correct:**
|
||||
|
||||
```java
|
||||
Object val = hashMap.get("eagler");
|
||||
if(val != null) {
|
||||
// do something with val
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Cache the return value of a function if you plan to use it multiple times
|
||||
|
||||
This is somewhat an extension of rule #2, don't repeatedly call the same function multiple times if there's no reason to, even if its a relatively fast function. Everything is slower and less efficient in a browser.
|
||||
|
||||
**Incorrect:**
|
||||
|
||||
```java
|
||||
while(itr.hasNext()) {
|
||||
if(!Minecraft.getMinecraft().getRenderManager().getEntityClassRenderObject(SomeEntity.class).shouldRender(itr.next())) {
|
||||
itr.remove();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Correct:**
|
||||
|
||||
```java
|
||||
Render<SomeEntity> render = Minecraft.getMinecraft().getRenderManager().getEntityClassRenderObject(SomeEntity.class);
|
||||
while(itr.hasNext()) {
|
||||
if(!render.shouldRender(itr.next())) {
|
||||
itr.remove();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Iterators aren't that great
|
||||
|
||||
Avoid using iterators when possible, this includes a `for(Item item : list)` type loop, since this may compile into bytecode that uses an iterator. If the list is a linked list or some other type of data structure that can’t perform random access efficiently, then it is recommended to use an iterator, but if the collection is guaranteed to be something similar to an ArrayList then implement it via a traditional for loop instead.
|
||||
|
||||
**Recommended way to iterate an ArrayList:**
|
||||
|
||||
```java
|
||||
for(int i = 0, l = list.size(); i < l; ++i) {
|
||||
Item item = list.get(i);
|
||||
// do something
|
||||
}
|
||||
```
|
||||
|
||||
### 5. Don't shit on the heap
|
||||
|
||||
Avoid creating temporary single-use objects in performance critical code, since the overhead of doing so is larger in a browser where there’s no type safety to predefine object structures. This includes using lambdas or using most of the stuff in the google guava package. Also this is partially why I prefer not using iterators whenever possible.
|
||||
|
||||
**Incorrect, creates 5 temporary objects:**
|
||||
|
||||
```java
|
||||
List<String> list1 = Arrays.asList("eagler", "eagler", "deevis");
|
||||
List<String> list2 = Lists.newArrayList(
|
||||
Collections2.transform(
|
||||
Collections2.filter(
|
||||
list1,
|
||||
(e) -> !e.equals("deevis")
|
||||
),
|
||||
(e) -> (e + "!")
|
||||
)
|
||||
);
|
||||
```
|
||||
|
||||
**Correct, creates no temporary objects:**
|
||||
|
||||
```java
|
||||
List<String> list1 = Arrays.asList("eagler", "eagler", "deevis");
|
||||
List<String> list2 = Lists.newArrayList();
|
||||
for(int i = 0, l = list1.size(); i < l; ++i) {
|
||||
String s = list1.get(i);
|
||||
if(!s.equals("deevis")) {
|
||||
list2.add(s + "!");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
(note: we are ignoring the StringBuilder instances that the compiler generates from ` + "!"`)
|
||||
|
||||
### 6. Don't base game/render logic off of the system time
|
||||
|
||||
Use `EagRuntime.steadyTimeMillis()` instead to access a monotonic clock, as in a clock that is guaranteed to only run forwards, and is not affected by changes in the system time. `System.currentTimeMillis()` should only be used in situations where you want to know the actual wall time or are measuring elapsed time across multiple page refreshes.
|
||||
|
||||
### 7. Prefer multiplication over division
|
||||
|
||||
If you're always gonna divide a number by some constant, it is better to multiply it by one-over-the-constant instead.
|
||||
|
||||
**Incorrect**
|
||||
|
||||
```java
|
||||
float b = a / 50.0f;
|
||||
```
|
||||
|
||||
**Correct**
|
||||
|
||||
```java
|
||||
float b = a * 0.02f;
|
||||
```
|
||||
|
||||
### 8. Shaders should take advantage of compiler intrinsics
|
||||
|
||||
Although you may think these two pieces of code are identical, its more than likely that the "Correct" example will compile to a more efficient shader on almost any hardware. The functions in GLSL are not a library, they are compiler intrinsics that usually compile to inline assembly that can take advantage of different acceleration instructions in the GPU's instruction set. Vector math should be done in ways that promotes the use of SIMD instructions when the code is compiled to a shader.
|
||||
|
||||
**Incorrect:**
|
||||
|
||||
```glsl
|
||||
float dx = pos1.x - pos2.x;
|
||||
float dy = pos1.y - pos2.y;
|
||||
float dz = pos1.z - pos2.z;
|
||||
float distance = sqrt(dx * dx + dy * dy + dz * dz);
|
||||
float fogDensity = pow(2.718, -density * distance);
|
||||
```
|
||||
|
||||
**Correct:**
|
||||
|
||||
```glsl
|
||||
float fogDensity = exp(-density * length(pos1.xyz - pos2.xyz));
|
||||
```
|
||||
|
||||
### 9. Flatten the control flow of shaders
|
||||
|
||||
Modern GPUs are able to execute multiple instances of a shader on a single core, but if one of those shaders encounters a branch (if statement, or related) that causes it to begin executing different code from the other instances of the shader running on that core, that instance of the shader can no longer be executed at the same time as the other instances, and suddenly you've significantly increased the amount of time this core will now be busy executing shader instructions to account for all of the branches the different shader instances have taken.
|
||||
|
||||
**Incorrect:**
|
||||
|
||||
```glsl
|
||||
float lightValue = dot(lightDirection, normal);
|
||||
if(lightValue > 0.0) {
|
||||
color += lightValue * lightColor * diffuseColor;
|
||||
}
|
||||
```
|
||||
|
||||
**Correct:**
|
||||
|
||||
```glsl
|
||||
float lightValue = max(dot(lightDirection, normal), 0.0);
|
||||
color += lightValue * lightColor * diffuseColor;
|
||||
```
|
||||
|
||||
### 10. Use textureLod unless mipmapping is necessary
|
||||
|
||||
This will prevent the shader from wasting time trying to determine what mipmap levels to read from when the texture is sampled.
|
||||
|
||||
**Incorrect:**
|
||||
|
||||
```glsl
|
||||
float depthValue = texture(depthBuffer, pos).r;
|
||||
```
|
||||
|
||||
**Correct:**
|
||||
|
||||
```glsl
|
||||
float depthValue = textureLod(depthBuffer, pos, 0.0).r;
|
||||
```
|
||||
|
||||
### 11. Divide complex and branch-intensive shaders into multiple draw calls
|
||||
|
||||
You can use a variety of different blending modes to mathematically combine the results of shaders. This is done for the same reason as flattening the control flow, to try and keep instruction pointers in sync by periodically resetting their positions, and also to allow for the driver to multitask better on GPUs with insane numbers of cores. It also allows the shader’s execution to be distributed across multiple frames in the case of something that doesn’t need to update often (like clouds).
|
||||
|
||||
### 12. Don't abuse `@JSBody` in TeaVM code
|
||||
|
||||
TeaVM provides lots of ways of interacting with JavaScript, using `@JSBody` is not the only way, consider using an overlay type.
|
||||
|
||||
**Incorrect**
|
||||
|
||||
```java
|
||||
@JSObject(params = { "obj" }, script = "return obj.valueA;")
|
||||
public static native JSObject getValueA(JSObject obj);
|
||||
|
||||
@JSObject(params = { "obj" }, script = "return obj.valueB;")
|
||||
public static native JSObject getValueB(JSObject obj);
|
||||
|
||||
@JSObject(params = { "obj" }, script = "return obj.valueC;")
|
||||
public static native JSObject getValueC(JSObject obj);
|
||||
|
||||
@JSObject(params = { "obj" }, script = "obj.dumbFunction();")
|
||||
public static native void callDumbFunction(JSObject obj);
|
||||
```
|
||||
|
||||
**Correct**
|
||||
|
||||
```java
|
||||
public interface MyObject extends JSObject {
|
||||
|
||||
@JSProperty
|
||||
JSObject getValueA();
|
||||
|
||||
@JSProperty
|
||||
JSObject getValueB();
|
||||
|
||||
@JSProperty
|
||||
JSObject getValueC();
|
||||
|
||||
void dumbFunction();
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
### 13. Don't fall for TeaVM's threads
|
||||
|
||||
It is impossible to have multithreading in JavaScript, only worker objects can be used to execute code concurrently, which can't share javascript variables. Therefore, when you create a thread in TeaVM, you're creating a virtual thread that isn't capable of running at the same time as any other virtual thread in the TeaVM context. This means it's impossible to speed a TeaVM program up through the use of multiple Java threads, instead it is more than likely that it will just slow the program down more to implement multithreading through TeaVM's threads due to the additional time required for synchronization and context switches. Its more efficient to just program the entire application to be single threaded to begin with, just put everything in the main loop and realize that if it was in a different thread it would just periodically interrupt the main loop.
|
||||
|
||||
### 14. Always use try-with-resources
|
||||
|
||||
For any code that deals with streams to be considered safe, it should either use a try-with-resources or try/finally in order to release resources when complete, since otherwise the stream might not close if an IO error causes the function to return early. This is especially important for plugin code since its supposed to be able to run on a large server for weeks at a time without the underlying JVM being restarted. If hackers discover a bug in the code to cause a function to return early like this without closing a stream, they might exploit it to fatally crash the server by spamming whatever corrupt packet causes the function to leak the stream, so all code must be written so it can fail at any time without leaking resources.
|
||||
|
||||
**Incorrect**
|
||||
|
||||
```java
|
||||
InputStream is = new FileInputStream(new File("phile.txt"));
|
||||
is.write(someArray);
|
||||
is.close();
|
||||
```
|
||||
|
||||
**Correct**
|
||||
|
||||
```java
|
||||
try(InputStream is = new FileInputStream(new File("phile.txt"))) {
|
||||
is.write(someArray);
|
||||
}
|
||||
```
|
||||
|
||||
Notice that the `.close()` can be omitted completely when using a try-with-resources
|
||||
|
||||
### 15. Always close compression/decompression streams
|
||||
|
||||
In the desktop runtime, the default oracle JDK uses native code to implement the compression/decompression streams (InflaterInputStream, GZIPInputStream, etc) and therefore if you forget to close the compression/decompression stream it will cause a memory leak when the code isn't running in a browser. This is a common issue when using byte array input/output streams since you might believe when decompressing data from a byte array that there's no reason to close the stream when you're done since its not a file, but that will still cause a memory leak due to the decompression stream not being cleaned up.
|
||||
|
||||
## Part B. Project Structure
|
||||
|
||||
### 1. Code decompiled from Minecraft goes in `src/game/java`
|
||||
|
||||
Don't add any new classes to `src/game/java`, and ideally any significant additions to the game's source (functions, etc) should be done through creating new classes in `src/main/java` instead of adding it directly to the decompiled classes.
|
||||
|
||||
### 2. Do not put platform-dependent code in `src/main/java` or `src/game/java`
|
||||
|
||||
One of the objectives of Eaglercraft is to make Minecraft Java edition truly cross platform, why stop at just a desktop and JavaScript runtime? There are plans to create an Android runtime and several WebAssembly runtimes, all of which will be compatible with any pre-existing eaglercraft clients that only depend on the EaglercraftX runtime library and don't directly depend on components of TeaVM or LWJGL. Ideally, all core features of the client should be implemented in the `src/main/java` and `src/game/java` and any platform-dependent features should be stubbed out in some abstract platform-independent way in classes in the `src/teavm/java` and `src/lwjgl/java` and any other future runtime you want your client to support. Ideally, every source folder of platform-dependent code should expose an identical API for access to the platform-independent code as all the other platform-dependant code folders currently expose.
|
||||
|
||||
### 3. Don't mix JavaScript with Java
|
||||
|
||||
Don’t implement features in the JavaScript runtime by requiring additional JavaScript files be included on index.html, if you must access browser APIs then use the TeaVM JSO to write your code in Java instead so it’s baked directly into classes.js. Certain browser APIs may be missing from the default TeaVM JSO-APIs library but it is not difficult to create the overlay types for them manually. Clients that violate this rule may also not possible to automatically import into the EaglercraftX boot menu depending on how fucked up they are. There aren't any limitations to the TeaVM JSO that give you a good enough excuse not to follow this rule.
|
||||
|
||||
### 4. Don't access the classes named "Platform\*" directly from your platform-independent code
|
||||
|
||||
Much like the Java runtime environment itself, Eaglercraft's runtime library consists of two layers, the internal classes full of platform-dependent code that expose an intermediate API not meant to be used by programmers directly, and the platform-independent API classes that provide a platform-independent wrapper for the platform dependent classes and also provide all the miscellaneous utility functions that don't require platform dependent code to be implemented. Chances are if you are directly using a function on a class that has a name that starts with "Platform\*", that there is a different class in `src/main/java` that you are meant to use in order to access that feature, that may perform additional checks or adjust the values you are passing to the function before calling the function in the Platform class.
|
||||
|
||||
## Part C. Compatibility Standards
|
||||
|
||||
### 1. Target minimum JDK version is Java 8
|
||||
|
||||
Its difficult to find a platform where its not possible to run Java 8 in some capacity, therefore the desktop runtime of EaglercraftX and the BungeeCord plugin should target Java 8. The Velocity plugin is an exception since Velocity itself doesn't support Java 8 either.
|
||||
|
||||
### 2. Target minimum supported browser is Google Chrome 38
|
||||
|
||||
Released on October 7, 2014, we think its a good target for the JavaScript versions of EaglercraftX. This is the last version of Chrome that supports hardware accelerated WebGL 1.0 on Windows XP. All base features of the underlying Minecraft 1.8 client must be functional, however things such as EaglercraftX's shaders or dynamic lighting are not required to work. The client cannot crash as a result of any missing features on an old browser, you must either implement fallbacks or safely disable the unsupported features.
|
||||
|
||||
### 3. Target minimum supported graphics API is OpenGL ES 2.0 (WebGL 1.0)
|
||||
|
||||
The most widely supported graphics API in the world is currently OpenGL ES 2.0, so ideally that should be the target for EaglercraftX 1.8. We can guarantee the client will be on an OpenGL ES 3.0 context 99% of the time, however its not that hard to also maintain support for GLES 2.0 (WebGL 1.0) as well with slightly reduced functionality so we might as well make it a feature in case of the 1% of the time that functionality is not available. The client cannot depend on any GL extensions in order to run in GLES 2.0 mode, however its reasonable to assume there will be VAO support via extensions in most GLES 2.0 contexts so the client includes an abstraction layer (via EaglercraftGPU.java) to seamlessly emulate VAO functionality even when the client is running in GLES 2.0 mode with no VAO extensions. The only core feature of Minecraft 1.8 that is completely unavailable in GLES 2.0 mode is mip-mapping for the blocks/items texture atlas due to being unable to limit the max mipmap level.
|
||||
|
||||
### 4. Use preprocessor directives to make portable shaders that can be compiled for both OpenGL ES 2.0 and 3.0 contexts
|
||||
|
||||
Most of the shaders in the base "glsl" directory of the resources EPK file use a file called "gles2_compat.glsl" to polyfill certain GLSL features (such as input/output declarations) via preprocessor directives to allow them to be compiled on both OpenGL ES 3.0 and 2.0 contexts. This is the preferred way to implement backwards compatibility over creating seprate versions of the same shaders, since future developers don't need to waste time maintaining multiple versions of the same code if they don't really care about backwards compatibility in the first place.
|
||||
|
||||
### 5. Target minimum version of the JavaScript syntax is ES5 strict mode
|
||||
|
||||
A shim is included to provide certain ES6 functions, however you should always program with syntax compatible with ES5, so the script doesn't crash immediately due to syntax errors even if the functions that use unsupported syntax aren't actually being called. `build.gradle` currently patches out all the ES5 strict mode incompatible syntax in the output of TeaVM 0.9.2, but this will probably break if you try to update TeaVM. Don't worry though because future WASM versions of EaglercraftX will use the latest versions of TeaVM. **Some common incompatible syntax to avoid includes `const`, `let`, `async`, `( ) => `, and using named functions! You can't do any of these things in your JSBody annotations.**
|
||||
|
||||
### 6. You cannot depend on any deprecated browser features
|
||||
|
||||
The same way we want EaglercraftX to work on browsers from over 10 years ago, we want it to still work in browsers 10 years from today, therefore the client cannot depend on any deprecated browser features in order for all the base Minecraft 1.8 game's features to work properly. However it is okay to use deprecated features as fallback if any modern non-deprecated feature (such as keyboard event handling) that the game needs if the game is running in an old browser.
|
||||
|
||||
### 7. Always use addEventListener to register event handlers
|
||||
|
||||
Always use addEventListener to register event handlers for browser APIs, never through the use of assigning the legacy "on\*" (onclick, onkeydown, onmessage, etc) variables, the TeaVMUtils class has a universal helper function for accessing addEventListener on any JSO objects that don’t already implement the function.
|
||||
|
||||
### 8. JavaScript should be executed in strict mode
|
||||
|
||||
Always make sure your JavaScript files start with `"use strict";`, be careful when adding this to your code retroactively because it will probably break hastily written code unless you haven’t made a single typo that’s not forbidden in strict mode. Be aware that in Chrome 38 this means you can't use stuff such as `const` and `let` or named functions in any of your JSBody annotations!
|
||||
|
251
EaglerTools/GenerateBlocks.mjs
Normal file
@ -0,0 +1,251 @@
|
||||
import path from 'path';
|
||||
import fs from 'fs/promises';
|
||||
|
||||
let blockId = 695; // replace with next id
|
||||
|
||||
const basePath = path.dirname(path.dirname(path.resolve(import.meta.filename)));
|
||||
const sourceFolder = path.join(basePath, 'EaglerTools', 'makeBlock');
|
||||
const starlikeAssetsFolder = path.join(
|
||||
basePath,
|
||||
'desktopRuntime',
|
||||
'resources',
|
||||
'assets',
|
||||
'starlike',
|
||||
);
|
||||
|
||||
const blockTextureFolder = path.join(
|
||||
starlikeAssetsFolder,
|
||||
'textures',
|
||||
'blocks',
|
||||
);
|
||||
const blockModelFolder = path.join(starlikeAssetsFolder, 'models', 'block');
|
||||
const itemModelFolder = path.join(starlikeAssetsFolder, 'models', 'item');
|
||||
const blockstateFolder = path.join(starlikeAssetsFolder, 'blockstates');
|
||||
const langFilePath = path.join(starlikeAssetsFolder, 'lang', 'en_US.lang');
|
||||
|
||||
const itemsStarlikeJavaPath = path.join(
|
||||
basePath,
|
||||
'src',
|
||||
'main',
|
||||
'java',
|
||||
'net',
|
||||
'starlikeclient',
|
||||
'minecraft',
|
||||
'init',
|
||||
'ItemsStarlike.java',
|
||||
);
|
||||
const blocksJavaPath = path.join(
|
||||
basePath,
|
||||
'src',
|
||||
'game',
|
||||
'java',
|
||||
'net',
|
||||
'minecraft',
|
||||
'init',
|
||||
'Blocks.java',
|
||||
);
|
||||
|
||||
async function createDirectories() {
|
||||
await fs.mkdir(blockTextureFolder, { recursive: true });
|
||||
await fs.mkdir(blockModelFolder, { recursive: true });
|
||||
await fs.mkdir(itemModelFolder, { recursive: true });
|
||||
await fs.mkdir(blockstateFolder, { recursive: true });
|
||||
}
|
||||
|
||||
async function insertInFile(
|
||||
filePath,
|
||||
searchText,
|
||||
insertText,
|
||||
insertAfter = true,
|
||||
tabBefore = false,
|
||||
) {
|
||||
try {
|
||||
const content = await fs.readFile(filePath, 'utf8');
|
||||
const lines = content.split('\n');
|
||||
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
if (lines[i].includes(searchText)) {
|
||||
let insertLine = insertText + '\n';
|
||||
if (tabBefore) {
|
||||
insertLine = '\t' + insertLine;
|
||||
}
|
||||
if (insertAfter) {
|
||||
lines.splice(i + 1, 0, insertLine);
|
||||
} else {
|
||||
lines.splice(i, 0, insertLine);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
await fs.writeFile(filePath, lines.join('\n'));
|
||||
console.log(`Updated ${filePath} successfully.`);
|
||||
return true;
|
||||
} catch (err) {
|
||||
console.error(`Error with file ${filePath}: ${err}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
async function appendToFile(filePath, newLine) {
|
||||
try {
|
||||
await fs.appendFile(filePath, newLine + '\n');
|
||||
console.log(`Appended to ${filePath} successfully.`);
|
||||
} catch (err) {
|
||||
console.error(`Error appending to ${filePath}: ${err}`);
|
||||
}
|
||||
}
|
||||
|
||||
async function processBlocks() {
|
||||
console.log('Welcome to GenerateBlocks (EaglerTools)');
|
||||
console.log(
|
||||
'Drag the texture of the FULL block into the EaglerTools/makeBlock folder',
|
||||
);
|
||||
|
||||
try {
|
||||
const files = await fs.readdir(sourceFolder);
|
||||
|
||||
for (const filename of files) {
|
||||
if (!filename.endsWith('.png')) continue;
|
||||
|
||||
const blockName = path.parse(filename).name;
|
||||
const sourceImage = path.join(sourceFolder, filename);
|
||||
const destImage = path.join(blockTextureFolder, filename);
|
||||
|
||||
try {
|
||||
await fs.rename(sourceImage, destImage);
|
||||
console.log(`Moved image: ${filename} to ${destImage}`);
|
||||
|
||||
// Create blockstate data
|
||||
const blockModelData = {
|
||||
parent: 'block/cube_all',
|
||||
textures: {
|
||||
all: `starlike:blocks/${blockName}`,
|
||||
},
|
||||
};
|
||||
|
||||
// Create item model data
|
||||
const itemModelData = {
|
||||
parent: `starlike:block/${blockName}`,
|
||||
display: {
|
||||
thirdperson: {
|
||||
rotation: [10, -45, 170],
|
||||
translation: [0, 1.5, -2.75],
|
||||
scale: [0.375, 0.375, 0.375],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
// Create blockstate JSON data
|
||||
const blockstateData = {
|
||||
variants: {
|
||||
normal: {
|
||||
model: `starlike:${blockName}`,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
// Write JSON files
|
||||
await fs.writeFile(
|
||||
path.join(blockModelFolder, `${blockName}.json`),
|
||||
JSON.stringify(blockModelData, null, 4),
|
||||
);
|
||||
|
||||
await fs.writeFile(
|
||||
path.join(itemModelFolder, `${blockName}.json`),
|
||||
JSON.stringify(itemModelData, null, 4),
|
||||
);
|
||||
|
||||
await fs.writeFile(
|
||||
path.join(blockstateFolder, `${blockName}.json`),
|
||||
JSON.stringify(blockstateData, null, 4),
|
||||
);
|
||||
|
||||
// Determine material properties
|
||||
let materialType = 'Material.rock';
|
||||
let hardness = '1.5f';
|
||||
let resistance = '10.0f';
|
||||
let soundType = 'soundTypePiston';
|
||||
|
||||
if (/log|planks|wood/.test(blockName)) {
|
||||
materialType = 'Material.wood';
|
||||
hardness = '0.5f';
|
||||
resistance = '10.0f';
|
||||
soundType = 'soundTypeWood';
|
||||
} else if (/steel|iron|grate|bar|copper|gold/.test(blockName)) {
|
||||
materialType = 'Material.iron';
|
||||
hardness = '5f';
|
||||
resistance = '10.0f';
|
||||
soundType = 'soundTypeMetal';
|
||||
} else if (/dirt|grass/.test(blockName)) {
|
||||
materialType = 'Material.ground';
|
||||
hardness = '0.5f';
|
||||
resistance = '1f';
|
||||
soundType = 'soundTypeGround';
|
||||
}
|
||||
|
||||
// Generate and insert Java code
|
||||
const registrationLine =
|
||||
`Block.registerBlock(${blockId}, "starlike:${blockName}", ` +
|
||||
`(new Block(${materialType}, MapColor.purpleColor)).setHardness(${hardness}).setResistance(${resistance}) ` +
|
||||
`.setStepSound(Block.${soundType}).setUnlocalizedName("${blockName}").setCreativeTab(CreativeTabs.tabStarlike));`;
|
||||
|
||||
await insertInFile(
|
||||
itemsStarlikeJavaPath,
|
||||
'//autogenerateequals',
|
||||
registrationLine,
|
||||
);
|
||||
|
||||
const blockDeclaration = ` public static Block ${blockName};`;
|
||||
const getRegisteredLine = ` ${blockName} = getRegisteredBlock("starlike:${blockName}");`;
|
||||
|
||||
await insertInFile(
|
||||
blocksJavaPath,
|
||||
'//autogeneratevar',
|
||||
blockDeclaration,
|
||||
);
|
||||
await insertInFile(
|
||||
blocksJavaPath,
|
||||
'//autogenerateequals',
|
||||
getRegisteredLine,
|
||||
);
|
||||
|
||||
const itemBlockRegistration = `Item.registerItemBlock(Blocks.${blockName});`;
|
||||
await insertInFile(
|
||||
itemsStarlikeJavaPath,
|
||||
'//autogenerateregisterblock',
|
||||
itemBlockRegistration,
|
||||
true,
|
||||
true,
|
||||
);
|
||||
|
||||
const itemBlockRenderRegistration = `e.registerBlock(Blocks.${blockName},"starlike:${blockName}");`;
|
||||
await insertInFile(
|
||||
itemsStarlikeJavaPath,
|
||||
'//autogeneraterender',
|
||||
itemBlockRenderRegistration,
|
||||
true,
|
||||
true,
|
||||
);
|
||||
|
||||
const langEntry = `tile.${blockName}.name=${
|
||||
blockName.replace('_', ' ').charAt(0).toUpperCase() +
|
||||
blockName.slice(1)
|
||||
}`;
|
||||
await appendToFile(langFilePath, langEntry);
|
||||
|
||||
blockId++;
|
||||
} catch (err) {
|
||||
console.error(`Error processing ${filename}: ${err}`);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(`Error reading source folder: ${err}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Run the script
|
||||
createDirectories()
|
||||
.then(() => processBlocks())
|
||||
.catch((err) => console.error('Error:', err));
|
173
EaglerTools/GenerateBlocks.py
Normal file
@ -0,0 +1,173 @@
|
||||
import os
|
||||
import shutil
|
||||
import json
|
||||
|
||||
base_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
source_folder = os.path.join(base_path,"EaglerTools", "makeBlock")
|
||||
block_texture_folder = os.path.join(base_path, "desktopRuntime", "resources", "assets", "starlike", "textures", "blocks")
|
||||
block_model_folder = os.path.join(base_path, "desktopRuntime", "resources", "assets", "starlike", "models", "block")
|
||||
item_model_folder = os.path.join(base_path, "desktopRuntime", "resources", "assets", "starlike", "models", "item")
|
||||
blockstate_folder = os.path.join(base_path,"desktopRuntime", "resources", "assets","starlike", "blockstates")
|
||||
lang_file_path = os.path.join(base_path,"desktopRuntime", "resources", "assets","starlike", "lang", "en_US.lang")
|
||||
|
||||
os.makedirs(block_texture_folder, exist_ok=True)
|
||||
os.makedirs(block_model_folder, exist_ok=True)
|
||||
os.makedirs(item_model_folder, exist_ok=True)
|
||||
os.makedirs(blockstate_folder, exist_ok=True)
|
||||
|
||||
|
||||
items_starlike_java_path = os.path.join(
|
||||
base_path, "src", "main", "java", "net", "starlikeclient", "minecraft", "init", "ItemsStarlike.java"
|
||||
)
|
||||
blocks_java_path = os.path.join(base_path,"src", "game", "java", "net", "minecraft", "init", "Blocks.java")
|
||||
|
||||
blockId = 695; #replace with next id
|
||||
def insert_in_file(file_path, search_text, insert_text, insert_after=True, tab_before=False):
|
||||
try:
|
||||
with open(file_path, 'r') as file:
|
||||
lines = file.readlines()
|
||||
except Exception as e:
|
||||
print(f"Error reading {file_path}: {e}")
|
||||
return False
|
||||
|
||||
for i, line in enumerate(lines):
|
||||
if search_text in line:
|
||||
insert_line = insert_text + '\n'
|
||||
if tab_before:
|
||||
insert_line = '\t' + insert_line
|
||||
if insert_after:
|
||||
lines.insert(i + 1, insert_line)
|
||||
else:
|
||||
lines.insert(i, insert_line)
|
||||
break
|
||||
|
||||
try:
|
||||
with open(file_path, 'w') as file:
|
||||
file.writelines(lines)
|
||||
print(f"Updated {file_path} successfully.")
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"Error writing to {file_path}: {e}")
|
||||
return False
|
||||
|
||||
def append_to_file(file_path, new_line):
|
||||
try:
|
||||
with open(file_path, 'a') as file:
|
||||
file.write(new_line + '\n')
|
||||
print(f"Appended to {file_path} successfully.")
|
||||
except Exception as e:
|
||||
print(f"Error appending to {file_path}: {e}")
|
||||
|
||||
print("Welcome to GenerateBlocks (EaglerTools)")
|
||||
print("Drag the texture of the FULL block into the ")
|
||||
for filename in os.listdir(source_folder):
|
||||
if filename.endswith(".png"):
|
||||
|
||||
block_name = os.path.splitext(filename)[0]
|
||||
|
||||
source_image = os.path.join(source_folder, filename)
|
||||
dest_image = os.path.join(block_texture_folder, filename)
|
||||
|
||||
try:
|
||||
shutil.move(source_image, dest_image)
|
||||
print(f"Moved image: {filename} to {dest_image}")
|
||||
except Exception as e:
|
||||
print(f"Error moving file {filename}: {e}")
|
||||
continue
|
||||
|
||||
blockstate_data = {
|
||||
"parent": "block/cube_all",
|
||||
"textures": {
|
||||
"all": f"starlike:blocks/{block_name}"
|
||||
}
|
||||
}
|
||||
blockstate_path = os.path.join(block_model_folder, f"{block_name}.json")
|
||||
try:
|
||||
with open(blockstate_path, 'w') as blockstate_file:
|
||||
json.dump(blockstate_data, blockstate_file, indent=4)
|
||||
print(f"Created blockstate JSON: {blockstate_path}")
|
||||
except Exception as e:
|
||||
print(f"Error writing blockstate JSON for {block_name}: {e}")
|
||||
continue
|
||||
|
||||
item_model_data = {
|
||||
"parent": f"starlike:block/{block_name}",
|
||||
"display": {
|
||||
"thirdperson": {
|
||||
"rotation": [10, -45, 170],
|
||||
"translation": [0, 1.5, -2.75],
|
||||
"scale": [0.375, 0.375, 0.375]
|
||||
}
|
||||
}
|
||||
}
|
||||
item_model_path = os.path.join(item_model_folder, f"{block_name}.json")
|
||||
try:
|
||||
with open(item_model_path, 'w') as item_model_file:
|
||||
json.dump(item_model_data, item_model_file, indent=4)
|
||||
print(f"Created item model JSON: {item_model_path}")
|
||||
except Exception as e:
|
||||
print(f"Error writing item model JSON for {block_name}: {e}")
|
||||
continue
|
||||
|
||||
blockstate_json_data = {
|
||||
"variants": {
|
||||
"normal": {
|
||||
"model": f"starlike:{block_name}"
|
||||
}
|
||||
}
|
||||
}
|
||||
blockstate_json_path = os.path.join(blockstate_folder, f"{block_name}.json")
|
||||
try:
|
||||
with open(blockstate_json_path, 'w') as blockstate_json_file:
|
||||
json.dump(blockstate_json_data, blockstate_json_file, indent=4)
|
||||
print(f"Created blockstate JSON: {blockstate_json_path}")
|
||||
except Exception as e:
|
||||
print(f"Error writing blockstate JSON for {block_name}: {e}")
|
||||
continue
|
||||
|
||||
material_type = "Material.wood"
|
||||
hardness = "0.5f"
|
||||
resistance = "5.0f"
|
||||
soundType = "soundTypePiston"
|
||||
if any(keyword in block_name for keyword in ["log", "planks", "wood"]):
|
||||
material_type = "Material.wood"
|
||||
hardness = "0.5f"
|
||||
resistance = "10.0f"
|
||||
soundType = "soundTypeWood"
|
||||
elif any(keyword in block_name for keyword in ["steel", "iron", "grate", "bar", "copper", "gold"]):
|
||||
material_type = "Material.iron"
|
||||
hardness = "5f"
|
||||
resistance = "10.0f"
|
||||
soundType = "soundTypeMetal"
|
||||
elif any(keyword in block_name for keyword in ["dirt", "grass"]):
|
||||
material_type = "Material.ground"
|
||||
hardness = "0.5f"
|
||||
resistance = "1f"
|
||||
soundType = "soundTypeGround"
|
||||
else:
|
||||
material_type = "Material.rock"
|
||||
hardness = "1.5f"
|
||||
resistance = "10.0f"
|
||||
soundType = "soundTypePiston"
|
||||
|
||||
registration_line = (
|
||||
f"Block.registerBlock({blockId}, \"starlike:{block_name}\", "
|
||||
f"(new Block({material_type}, MapColor.purpleColor)).setHardness({hardness}).setResistance({resistance}) "
|
||||
f".setStepSound(Block.{soundType}).setUnlocalizedName(\"{block_name}\").setCreativeTab(CreativeTabs.tabStarlike));"
|
||||
)
|
||||
insert_in_file(items_starlike_java_path, "//autogenerateequals", registration_line)
|
||||
|
||||
block_declaration = f" public static Block {block_name};"
|
||||
get_registered_line = f" {block_name} = getRegisteredBlock(\"starlike:{block_name}\");"
|
||||
insert_in_file(blocks_java_path, "//autogeneratevar", block_declaration)
|
||||
insert_in_file(blocks_java_path, "//autogenerateequals", get_registered_line)
|
||||
|
||||
item_block_registration = f"Item.registerItemBlock(Blocks.{block_name});"
|
||||
insert_in_file(items_starlike_java_path, "//autogenerateregisterblock", item_block_registration, tab_before=True)
|
||||
item_block_render_registration = f'e.registerBlock(Blocks.{block_name},"starlike:{block_name}");'
|
||||
insert_in_file(items_starlike_java_path, "//autogeneraterender", item_block_render_registration, tab_before=True)
|
||||
lang_entry = f"tile.{block_name}.name={block_name.replace('_', ' ').capitalize()}"
|
||||
append_to_file(lang_file_path, lang_entry)
|
||||
blockId += 1
|
||||
|
164
EaglerTools/UpdateEaglercraftVersion.sh
Executable file
@ -0,0 +1,164 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
echo '
|
||||
##################################################
|
||||
|
||||
You need Eclipse installed to use this script.
|
||||
|
||||
Import the Eclipse Clean Up profile from:
|
||||
./desktopRuntime/eclipseProject/starlike_basic_format.xml
|
||||
|
||||
##################################################
|
||||
'
|
||||
|
||||
if ! dos2unix -V &> /dev/null; then
|
||||
echo "Error: dos2unix is not installed. Please install it and try again."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
SCRIPT_DONE="0"
|
||||
TMP_DIR="$(mktemp -d)"
|
||||
|
||||
cleanup() {
|
||||
if [[ "$SCRIPT_DONE" != "1" ]]; then
|
||||
echo
|
||||
echo
|
||||
echo "Script interrupted, cleaning up..."
|
||||
echo
|
||||
|
||||
git branch -D update-branch 2>/dev/null || :
|
||||
rm -rf "$TMP_DIR"
|
||||
|
||||
if [[ -n "${CURRENT_BRANCH:-}" ]]; then
|
||||
git checkout -f "$CURRENT_BRANCH"
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "Cleaned up."
|
||||
SCRIPT_DONE="1"
|
||||
fi
|
||||
exit
|
||||
}
|
||||
|
||||
for sig in HUP INT QUIT ABRT ALRM TERM USR1 USR2 PIPE EXIT; do
|
||||
trap cleanup "$sig"
|
||||
done
|
||||
|
||||
echo
|
||||
echo "Starting script..."
|
||||
echo
|
||||
|
||||
git remote remove workspace
|
||||
git remote add workspace "https://git.eaglercraft.rip/eaglercraft/eaglercraft-1.8-workspace.git"
|
||||
git fetch workspace
|
||||
|
||||
echo
|
||||
echo
|
||||
echo "Here are the last 5 commits and their commit hashes:"
|
||||
git --no-pager log -n 5 --oneline workspace/master
|
||||
echo
|
||||
echo "What is the commit hash of the client's current update?"
|
||||
echo "(e.g. the client is currently on u40 and the latest is u42, type the commit hash of u40)"
|
||||
read -rp "> " CURRENT_HASH
|
||||
echo
|
||||
echo
|
||||
if ! git rev-parse "$CURRENT_HASH" &> /dev/null; then
|
||||
echo "Invalid hash: $CURRENT_HASH"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
CURRENT_BRANCH="$(git branch --show-current)"
|
||||
git stash -u
|
||||
echo
|
||||
echo
|
||||
echo "All current working changes have been stashed."
|
||||
echo "You can apply them by running \`git stash apply\`."
|
||||
echo
|
||||
echo
|
||||
git checkout -f "$CURRENT_BRANCH"
|
||||
git reset --hard "$CURRENT_BRANCH"
|
||||
echo
|
||||
echo
|
||||
echo "Run Clean Up in Eclipse using the imported profile"
|
||||
echo "Press enter to continue..."
|
||||
read -r
|
||||
echo
|
||||
echo
|
||||
git add -A
|
||||
FORMAT_COMMIT="0"
|
||||
if git commit -m 'format'; then
|
||||
FORMAT_COMMIT="1"
|
||||
fi
|
||||
|
||||
git checkout -f workspace/master
|
||||
git reset --hard workspace/master
|
||||
cp -r . "$TMP_DIR"
|
||||
rm -rf "$TMP_DIR"/.git
|
||||
|
||||
git branch -D update-branch || :
|
||||
git checkout -b update-branch "$CURRENT_HASH"
|
||||
git reset --hard "$CURRENT_HASH"
|
||||
echo
|
||||
echo
|
||||
echo "Run Clean Up in Eclipse using the imported profile"
|
||||
echo "Press enter to continue..."
|
||||
read -r
|
||||
echo
|
||||
echo
|
||||
find . -type f -print0 | xargs -0 dos2unix || :
|
||||
find . -type f -print0 | xargs -0 chmod -x || :
|
||||
chmod +x ./gradlew ./*.sh
|
||||
git add -A
|
||||
git commit --amend -m "$(git log -n 1 --format='%s' "$CURRENT_HASH")" -m "$(git log -n 1 --format='%b' "$CURRENT_HASH")"
|
||||
|
||||
cp -r "$TMP_DIR"/ ./
|
||||
rm -rf "$TMP_DIR"
|
||||
echo
|
||||
echo
|
||||
echo "Run Clean Up in Eclipse using the imported profile"
|
||||
echo "Press enter to continue..."
|
||||
read -r
|
||||
echo
|
||||
echo
|
||||
find . -type f -print0 | xargs -0 dos2unix || :
|
||||
find . -type f -print0 | xargs -0 chmod -x || :
|
||||
chmod +x ./gradlew ./*.sh
|
||||
git add -A
|
||||
git commit -m "$(git log -n 1 --format='%s' workspace/master)" -m "$(git log -n 1 --format='%b' workspace/master)"
|
||||
|
||||
git checkout -f "$CURRENT_BRANCH"
|
||||
git reset --hard "$CURRENT_BRANCH"
|
||||
if ! git cherry-pick -n "$(git log -n 1 --format="%H" update-branch)"; then
|
||||
echo
|
||||
echo
|
||||
echo "Fix all merge conflicts before continuing."
|
||||
echo "Press enter to continue..."
|
||||
read -r
|
||||
echo
|
||||
echo
|
||||
fi
|
||||
|
||||
git add -A
|
||||
echo
|
||||
echo
|
||||
while [[ -z "${COMMIT_NAME:-}" ]]; do
|
||||
echo "Please enter a commit name."
|
||||
read -rp "> " COMMIT_NAME
|
||||
done
|
||||
echo
|
||||
echo
|
||||
if [[ "$FORMAT_COMMIT" == "1" ]]; then
|
||||
git commit --amend -m "$COMMIT_NAME"
|
||||
else
|
||||
git commit -m "$COMMIT_NAME"
|
||||
fi
|
||||
|
||||
git branch -D update-branch
|
||||
|
||||
echo
|
||||
echo
|
||||
echo "Done!"
|
||||
SCRIPT_DONE="1"
|
||||
exit
|
33
LICENSE.md
Normal file
@ -0,0 +1,33 @@
|
||||
# Starlike License
|
||||
|
||||
Copyright (c) 2024 zumbiepig and SpeedSlicer
|
||||
|
||||
## 1. Attribution
|
||||
|
||||
If you use any part of this code in your project, you **must credit** the original authors, zumbiepig and SpeedSlicer, in a clearly visible manner in both the project documentation and the software interface, including but not limited to:
|
||||
|
||||
- **Credits section** in documentation
|
||||
- **Main menu or splash screen** within the application
|
||||
|
||||
The **main menu** of the software or application **must not be changed** without written permission from _both_ zumbiepig and SpeedSlicer.
|
||||
|
||||
## 2. Open Source Requirement for Derivative Works
|
||||
|
||||
If you create any derivative work (a "fork") based on this project:
|
||||
|
||||
- You **must release the source code** of the derivative work under this same license, ensuring that all forks and modifications remain open source.
|
||||
- You **must clearly state** that the original code is based on work by zumbiepig and SpeedSlicer.
|
||||
|
||||
## 3. Restrictions
|
||||
|
||||
- You are **not allowed to remove or alter any credits** to zumbiepig and SpeedSlicer in the code or the user interface.
|
||||
- You **cannot distribute** any modified version of this code under a more restrictive license.
|
||||
- Any attempts to circumvent or alter these licensing terms are strictly prohibited.
|
||||
|
||||
## 4. Warranty Disclaimer
|
||||
|
||||
This software is provided "as is", without any warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose, and non-infringement. In no event shall the author be liable for any claim, damages, or other liability, whether in an action of contract, tort, or otherwise, arising from, out of, or in connection with the software or the use or other dealings in the software.
|
||||
|
||||
---
|
||||
|
||||
By using this code, you agree to the terms of this license.
|
@ -1,4 +1,4 @@
|
||||
@echo off
|
||||
title MakeOfflineDownload
|
||||
java -cp "desktopRuntime/MakeOfflineDownload.jar;desktopRuntime/CompileEPK.jar" net.lax1dude.eaglercraft.v1_8.buildtools.workspace.MakeOfflineDownload "javascript/OfflineDownloadTemplate.txt" "javascript/classes.js" "javascript/assets.epk" "NUL" "javascript/Starlike_Client_Offline.html" "javascript/lang"
|
||||
java -cp "desktopRuntime/MakeOfflineDownload.jar;desktopRuntime/CompileEPK.jar" net.lax1dude.eaglercraft.v1_8.buildtools.workspace.MakeOfflineDownload "desktopRuntime/resources/OfflineDownloadTemplate.txt" "javascript/classes.js" "javascript/assets.epk" "javascript/Starlike_Client_Offline.html"
|
||||
pause
|
||||
|
2
MakeOfflineDownload.sh
Normal file → Executable file
@ -1,2 +1,2 @@
|
||||
#!/bin/sh
|
||||
java -cp "desktopRuntime/MakeOfflineDownload.jar:desktopRuntime/CompileEPK.jar" net.lax1dude.eaglercraft.v1_8.buildtools.workspace.MakeOfflineDownload "javascript/OfflineDownloadTemplate.txt" "javascript/classes.js" "javascript/assets.epk" "/dev/null" "javascript/Starlike_Client_Offline.html" "javascript/lang"
|
||||
java -cp "desktopRuntime/MakeOfflineDownload.jar:desktopRuntime/CompileEPK.jar" net.lax1dude.eaglercraft.v1_8.buildtools.workspace.MakeOfflineDownload "desktopRuntime/resources/OfflineDownloadTemplate.txt" "javascript/classes.js" "javascript/assets.epk" "javascript/Starlike_Client_Offline.html"
|
||||
|
@ -1,4 +1,4 @@
|
||||
@echo off
|
||||
title MakeSignedClient
|
||||
java -cp "desktopRuntime/MakeOfflineDownload.jar;desktopRuntime/CompileEPK.jar" net.lax1dude.eaglercraft.v1_8.buildtools.workspace.MakeSignedClient "javascript/SignedBundleTemplate.txt" "javascript/classes.js" "javascript/assets.epk" "javascript/lang" "javascript/SignedClientTemplate.txt" "javascript/UpdateDownloadSources.txt" "javascript/EaglercraftX_1.8_Offline_Signed_Client.html"
|
||||
pause
|
||||
java -cp "desktopRuntime/MakeOfflineDownload.jar;desktopRuntime/CompileEPK.jar" net.lax1dude.eaglercraft.v1_8.buildtools.workspace.MakeSignedClient "desktopRuntime/resources/SignedBundleTemplate.txt" "javascript/classes.js" "javascript/assets.epk" "desktopRuntime/resources/SignedClientTemplate.txt" "desktopRuntime/resources/UpdateDownloadSources.txt" "javascript/Starlike_Client_Offline_Signed.html"
|
||||
pause
|
||||
|
2
MakeSignedClient.sh
Normal file → Executable file
@ -1,2 +1,2 @@
|
||||
#!/bin/sh
|
||||
java -cp "desktopRuntime/MakeOfflineDownload.jar:desktopRuntime/CompileEPK.jar" net.lax1dude.eaglercraft.v1_8.buildtools.workspace.MakeSignedClient "javascript/SignedBundleTemplate.txt" "javascript/classes.js" "javascript/assets.epk" "javascript/lang" "javascript/SignedClientTemplate.txt" "javascript/UpdateDownloadSources.txt" "javascript/EaglercraftX_1.8_Offline_Signed_Client.html"
|
||||
java -cp "desktopRuntime/MakeOfflineDownload.jar:desktopRuntime/CompileEPK.jar" net.lax1dude.eaglercraft.v1_8.buildtools.workspace.MakeSignedClient "desktopRuntime/resources/SignedBundleTemplate.txt" "javascript/classes.js" "javascript/assets.epk" "desktopRuntime/resources/SignedClientTemplate.txt" "desktopRuntime/resources/UpdateDownloadSources.txt" "javascript/Starlike_Client_Offline_Signed.html"
|
||||
|
28
README.md
@ -1,27 +1 @@
|
||||
### Java 17 is recommended for compiling to TeaVM
|
||||
|
||||
### Java 8 or greater is required for the desktop runtime
|
||||
|
||||
**Most Java IDEs will allow you to import this repository as a gradle project for compiling it to JavaScript.**
|
||||
|
||||
Java must be added to your PATH!
|
||||
|
||||
**To compile the web client:**
|
||||
1. Run `CompileEPK`
|
||||
2. Run `CompileJS` (or the `generateJavaScript` gradle task in your IDE)
|
||||
3. Check the "javascript" folder
|
||||
|
||||
**To compile an offline download:**
|
||||
1. Run `CompileEPK`
|
||||
2. Run `CompileJS` (or the `generateJavaScript` gradle task in your IDE)
|
||||
3. Run `MakeOfflineDownload`
|
||||
4. Check the "javascript" folder
|
||||
|
||||
**To use the desktop runtime:**
|
||||
1. Import the Eclipse project in "desktopRuntime/eclipseProject" into your IDE
|
||||
2. Open one of the .java files from the source folders (workaround for a bug)
|
||||
3. Run/Debug the client with the included "eaglercraftDebugRuntime" configuration
|
||||
|
||||
**See the main 1.8 repository's README for more info**
|
||||
|
||||
The source codes of EaglercraftXBungee and EaglercraftXVelocity are not included here.
|
||||
# Starlike Client
|
||||
|
40
build.gradle
@ -25,7 +25,17 @@ sourceSets {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
desktop {
|
||||
java {
|
||||
srcDirs(
|
||||
"src/main/java",
|
||||
"src/game/java",
|
||||
"src/protocol-game/java",
|
||||
"src/protocol-relay/java",
|
||||
"src/lwjgl/java"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
@ -36,16 +46,19 @@ dependencies {
|
||||
teavm(teavm.libs.jso)
|
||||
teavm(teavm.libs.jsoApis)
|
||||
compileOnly "org.teavm:teavm-core:0.9.2" // workaround for a few hacks
|
||||
|
||||
desktopImplementation fileTree("desktopRuntime/eclipseProject/deps_fix")
|
||||
}
|
||||
|
||||
def folder = "javascript"
|
||||
def name = "classes.js"
|
||||
|
||||
teavm.js {
|
||||
compileJava.options.encoding = "UTF-8"
|
||||
obfuscated = true
|
||||
sourceMap = true
|
||||
targetFileName = "../" + name
|
||||
optimization = OptimizationLevel.BALANCED // Change to "AGGRESSIVE" for release
|
||||
optimization = OptimizationLevel.AGGRESSIVE // Change to "AGGRESSIVE" for release
|
||||
outOfProcess = false
|
||||
fastGlobalAnalysis = false
|
||||
processMemory = 512
|
||||
@ -58,15 +71,32 @@ teavm.js {
|
||||
|
||||
tasks.named("generateJavaScript") {
|
||||
doLast {
|
||||
|
||||
delete file(folder + "/js")
|
||||
|
||||
// NOTE: This step may break at any time, and is not required for 99% of browsers
|
||||
|
||||
|
||||
def phile = file(folder + "/" + name)
|
||||
def dest = phile.getText("UTF-8")
|
||||
def i = dest.substring(0, dest.indexOf("=\$rt_globals.Symbol('jsoClass');")).lastIndexOf("let ")
|
||||
dest = dest.substring(0, i) + "var" + dest.substring(i + 3)
|
||||
def j = dest.indexOf("function(\$rt_globals,\$rt_exports){")
|
||||
dest = dest.substring(0, j + 34) + "\n" + file(folder + "/ES6ShimScript.txt").getText("UTF-8") + "\n" + dest.substring(j + 34)
|
||||
dest = dest.substring(0, j + 34) + "\n" + file("desktopRuntime/resources/ES6ShimScript.txt").getText("UTF-8") + "\n" + dest.substring(j + 34)
|
||||
phile.write(dest, "UTF-8")
|
||||
}
|
||||
}
|
||||
|
||||
tasks.register('runclient', JavaExec) {
|
||||
classpath = sourceSets.desktop.compileClasspath
|
||||
group = "EaglercraftX"
|
||||
description = "Runs the client"
|
||||
classpath sourceSets.desktop.runtimeClasspath
|
||||
jvmArgs '-Djava.library.path=.'
|
||||
if (System.getProperty("os.name").toLowerCase().contains("mac")) {
|
||||
jvmArgs '-Djava.library.path=. -XstartOnFirstThread'
|
||||
}
|
||||
|
||||
args = ["hide-renderdoc"]
|
||||
|
||||
workingDir "./desktopRuntime"
|
||||
main 'net.lax1dude.eaglercraft.v1_8.internal.lwjgl.MainClass'
|
||||
}
|
1
designModels/starlike/sc.bbmodel
Normal file
1
designModels/starlike/starlike-starlike.bbmodel
Normal file
1
designModels/starlike/starlikeclient-com.bbmodel
Normal file
1
designModels/watcher/Watcher.bbmodel
Normal file
46
designModels/watcher/watcher.java
Normal file
@ -0,0 +1,46 @@
|
||||
// Made with Blockbench 4.11.2
|
||||
// Exported for Minecraft version 1.7 - 1.12
|
||||
// Paste this class into your mod and generate all required imports
|
||||
|
||||
|
||||
public class Watcher extends ModelBase {
|
||||
private final ModelRenderer leg2;
|
||||
private final ModelRenderer leg3;
|
||||
private final ModelRenderer head;
|
||||
private final ModelRenderer leg;
|
||||
|
||||
public Watcher() {
|
||||
textureWidth = 64;
|
||||
textureHeight = 64;
|
||||
|
||||
leg2 = new ModelRenderer(this);
|
||||
leg2.setRotationPoint(0.0F, 24.0F, 0.0F);
|
||||
leg2.cubeList.add(new ModelBox(leg2, 20, 17, -4.0F, -6.0F, -12.0F, 2, 2, 8, 0.0F, false));
|
||||
|
||||
leg3 = new ModelRenderer(this);
|
||||
leg3.setRotationPoint(-3.0F, 0.0F, -5.0F);
|
||||
leg3.cubeList.add(new ModelBox(leg3, 0, 27, 4.0F, 16.0F, -7.0F, 2, 2, 8, 0.0F, false));
|
||||
|
||||
head = new ModelRenderer(this);
|
||||
head.setRotationPoint(-3.0F, 0.0F, -5.0F);
|
||||
head.cubeList.add(new ModelBox(head, 0, 0, -1.0F, 16.0F, 1.0F, 8, 8, 9, 0.0F, false));
|
||||
|
||||
leg = new ModelRenderer(this);
|
||||
leg.setRotationPoint(0.0F, 24.0F, 0.0F);
|
||||
leg.cubeList.add(new ModelBox(leg, 0, 17, -1.0F, -3.0F, -12.0F, 2, 2, 8, 0.0F, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5) {
|
||||
leg2.render(f5);
|
||||
leg3.render(f5);
|
||||
head.render(f5);
|
||||
leg.render(f5);
|
||||
}
|
||||
|
||||
public void setRotationAngle(ModelRenderer modelRenderer, float x, float y, float z) {
|
||||
modelRenderer.rotateAngleX = x;
|
||||
modelRenderer.rotateAngleY = y;
|
||||
modelRenderer.rotateAngleZ = z;
|
||||
}
|
||||
}
|
BIN
designModels/watcher/watcher.png
Normal file
After Width: | Height: | Size: 391 B |
@ -26,4 +26,4 @@ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
@ -511,4 +511,4 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
@ -29,4 +29,4 @@ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
26
desktopRuntime/eclipseProject/.classpath
Normal file
@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src_main_java"/>
|
||||
<classpathentry kind="src" path="src_game_java"/>
|
||||
<classpathentry kind="src" path="src_protocol-game_java"/>
|
||||
<classpathentry kind="src" path="src_protocol-relay_java"/>
|
||||
<classpathentry kind="src" path="src_lwjgl_java"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER">
|
||||
<attributes>
|
||||
<attribute name="module" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="lib" path="deps_fix/codecjorbis-20101023.jar"/>
|
||||
<classpathentry kind="lib" path="deps_fix/codecwav-20101023.jar"/>
|
||||
<classpathentry kind="lib" path="deps_fix/Java-WebSocket-1.5.1-with-dependencies.jar"/>
|
||||
<classpathentry kind="lib" path="deps_fix/lwjgl.jar"/>
|
||||
<classpathentry kind="lib" path="deps_fix/lwjgl-egl.jar"/>
|
||||
<classpathentry kind="lib" path="deps_fix/lwjgl-glfw.jar"/>
|
||||
<classpathentry kind="lib" path="deps_fix/lwjgl-jemalloc.jar"/>
|
||||
<classpathentry kind="lib" path="deps_fix/lwjgl-openal.jar"/>
|
||||
<classpathentry kind="lib" path="deps_fix/lwjgl-opengles.jar"/>
|
||||
<classpathentry kind="lib" path="deps_fix/soundsystem-20120107.jar"/>
|
||||
<classpathentry kind="lib" path="deps_fix/webrtc-java-0.8.0.jar"/>
|
||||
<classpathentry kind="lib" path="deps_fix/UnsafeMemcpy.jar"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
55
desktopRuntime/eclipseProject/.project
Normal file
@ -0,0 +1,55 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>eclipseProject</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
<linkedResources>
|
||||
<link>
|
||||
<name>src_game_java</name>
|
||||
<type>2</type>
|
||||
<locationURI>PARENT-2-PROJECT_LOC../src/game/java</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>src_lwjgl_java</name>
|
||||
<type>2</type>
|
||||
<locationURI>PARENT-2-PROJECT_LOC../src/lwjgl/java</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>src_main_java</name>
|
||||
<type>2</type>
|
||||
<locationURI>PARENT-2-PROJECT_LOC../src/main/java</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>src_protocol-game_java</name>
|
||||
<type>2</type>
|
||||
<locationURI>PARENT-2-PROJECT_LOC../src/protocol-game/java</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>src_protocol-relay_java</name>
|
||||
<type>2</type>
|
||||
<locationURI>PARENT-2-PROJECT_LOC../src/protocol-relay/java</locationURI>
|
||||
</link>
|
||||
</linkedResources>
|
||||
<filteredResources>
|
||||
<filter>
|
||||
<id>1734217596828</id>
|
||||
<name></name>
|
||||
<type>30</type>
|
||||
<matcher>
|
||||
<id>org.eclipse.core.resources.regexFilterMatcher</id>
|
||||
<arguments>node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
|
||||
</matcher>
|
||||
</filter>
|
||||
</filteredResources>
|
||||
</projectDescription>
|
@ -0,0 +1,26 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
|
||||
org.eclipse.jdt.core.compiler.annotation.nonnull=javax.annotation.Nonnull
|
||||
org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=javax.annotation.ParametersAreNonnullByDefault
|
||||
org.eclipse.jdt.core.compiler.annotation.nullable=javax.annotation.Nullable
|
||||
org.eclipse.jdt.core.compiler.annotation.nullanalysis=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=1.8
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=warning
|
||||
org.eclipse.jdt.core.compiler.problem.nullReference=warning
|
||||
org.eclipse.jdt.core.compiler.problem.nullSpecViolation=warning
|
||||
org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning
|
||||
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
|
||||
org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=enabled
|
||||
org.eclipse.jdt.core.compiler.release=disabled
|
||||
org.eclipse.jdt.core.compiler.source=1.8
|
@ -7,6 +7,9 @@
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
|
||||
<listEntry value="1"/>
|
||||
</listAttribute>
|
||||
<mapAttribute key="org.eclipse.debug.core.environmentVariables">
|
||||
<mapEntry key="LD_LIBRARY_PATH" value="${project_loc}/../"/>
|
||||
</mapAttribute>
|
||||
<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
|
||||
<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
|
||||
<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
|
||||
@ -17,6 +20,7 @@
|
||||
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="true"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="net.lax1dude.eaglercraft.v1_8.internal.lwjgl.MainClass"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.MODULE_NAME" value="eclipseProject"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="hide-renderdoc"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="eclipseProject"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Djava.library.path=."/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${project_loc}/../"/>
|
||||
|
147
desktopRuntime/eclipseProject/starlike_basic_format.xml
Normal file
@ -0,0 +1,147 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<profiles version="2">
|
||||
<profile kind="CleanUpProfile" name="Starlike: Basic format" version="2">
|
||||
<setting id="cleanup.use_autoboxing" value="false"/>
|
||||
<setting id="cleanup.remove_redundant_semicolons" value="false"/>
|
||||
<setting id="cleanup.system_property_file_separator" value="false"/>
|
||||
<setting id="cleanup.objects_equals" value="false"/>
|
||||
<setting id="cleanup.primitive_parsing" value="false"/>
|
||||
<setting id="cleanup.remove_trailing_whitespaces" value="true"/>
|
||||
<setting id="cleanup.remove_unused_private_fields" value="false"/>
|
||||
<setting id="cleanup.try_with_resource" value="false"/>
|
||||
<setting id="cleanup.system_property" value="false"/>
|
||||
<setting id="cleanup.add_missing_nls_tags" value="false"/>
|
||||
<setting id="cleanup.stringbuilder" value="false"/>
|
||||
<setting id="cleanup.push_down_negation" value="false"/>
|
||||
<setting id="cleanup.system_property_path_separator" value="false"/>
|
||||
<setting id="cleanup.also_simplify_lambda" value="false"/>
|
||||
<setting id="cleanup.use_var" value="false"/>
|
||||
<setting id="cleanup.use_blocks_only_for_return_and_throw" value="false"/>
|
||||
<setting id="cleanup.convert_functional_interfaces" value="false"/>
|
||||
<setting id="cleanup.make_type_abstract_if_missing_method" value="false"/>
|
||||
<setting id="cleanup.remove_private_constructors" value="false"/>
|
||||
<setting id="cleanup.evaluate_nullable" value="false"/>
|
||||
<setting id="cleanup.strictly_equal_or_different" value="false"/>
|
||||
<setting id="cleanup.system_property_boolean" value="false"/>
|
||||
<setting id="cleanup.embedded_if" value="false"/>
|
||||
<setting id="cleanup.join" value="false"/>
|
||||
<setting id="cleanup.return_expression" value="false"/>
|
||||
<setting id="cleanup.remove_unnecessary_casts" value="false"/>
|
||||
<setting id="cleanup.redundant_falling_through_block_end" value="false"/>
|
||||
<setting id="cleanup.overridden_assignment_move_decl" value="false"/>
|
||||
<setting id="cleanup.always_use_parentheses_in_expressions" value="false"/>
|
||||
<setting id="cleanup.use_parentheses_in_expressions" value="false"/>
|
||||
<setting id="cleanup.multi_catch" value="false"/>
|
||||
<setting id="cleanup.if_condition" value="false"/>
|
||||
<setting id="cleanup.comparison_statement" value="false"/>
|
||||
<setting id="cleanup.use_this_for_non_static_method_access_only_if_necessary" value="true"/>
|
||||
<setting id="cleanup.use_unboxing" value="false"/>
|
||||
<setting id="cleanup.bitwise_conditional_expression" value="false"/>
|
||||
<setting id="cleanup.remove_trailing_whitespaces_ignore_empty" value="false"/>
|
||||
<setting id="cleanup.instanceof" value="false"/>
|
||||
<setting id="cleanup.correct_indentation" value="true"/>
|
||||
<setting id="cleanup.make_private_fields_final" value="false"/>
|
||||
<setting id="cleanup.boolean_value_rather_than_comparison" value="false"/>
|
||||
<setting id="cleanup.qualify_static_member_accesses_with_declaring_class" value="false"/>
|
||||
<setting id="cleanup.no_string_creation" value="false"/>
|
||||
<setting id="cleanup.add_missing_override_annotations_interface_methods" value="true"/>
|
||||
<setting id="cleanup.substring" value="false"/>
|
||||
<setting id="cleanup.lazy_logical_operator" value="false"/>
|
||||
<setting id="cleanup.remove_unused_method_parameters" value="false"/>
|
||||
<setting id="cleanup.valueof_rather_than_instantiation" value="false"/>
|
||||
<setting id="cleanup.qualify_static_field_accesses_with_declaring_class" value="false"/>
|
||||
<setting id="cleanup.pull_out_if_from_if_else" value="false"/>
|
||||
<setting id="cleanup.use_anonymous_class_creation" value="false"/>
|
||||
<setting id="cleanup.stringconcat_stringbuffer_stringbuilder" value="false"/>
|
||||
<setting id="cleanup.convert_to_enhanced_for_loop_if_loop_var_used" value="false"/>
|
||||
<setting id="cleanup.replace_deprecated_calls" value="false"/>
|
||||
<setting id="cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class" value="false"/>
|
||||
<setting id="cleanup.break_loop" value="false"/>
|
||||
<setting id="cleanup.useless_continue" value="false"/>
|
||||
<setting id="cleanup.instanceof_keyword" value="false"/>
|
||||
<setting id="cleanup.standard_comparison" value="false"/>
|
||||
<setting id="cleanup.format_source_code" value="true"/>
|
||||
<setting id="cleanup.remove_unused_imports" value="true"/>
|
||||
<setting id="cleanup.use_lambda" value="true"/>
|
||||
<setting id="cleanup.map_cloning" value="false"/>
|
||||
<setting id="cleanup.no_super" value="false"/>
|
||||
<setting id="cleanup.extract_increment" value="false"/>
|
||||
<setting id="cleanup.always_use_this_for_non_static_field_access" value="false"/>
|
||||
<setting id="cleanup.add_missing_annotations" value="true"/>
|
||||
<setting id="cleanup.primitive_rather_than_wrapper" value="false"/>
|
||||
<setting id="cleanup.remove_unnecessary_nls_tags" value="false"/>
|
||||
<setting id="cleanup.remove_unused_private_methods" value="false"/>
|
||||
<setting id="cleanup.qualify_static_member_accesses_through_instances_with_declaring_class" value="false"/>
|
||||
<setting id="cleanup.always_use_this_for_non_static_method_access" value="false"/>
|
||||
<setting id="cleanup.primitive_serialization" value="false"/>
|
||||
<setting id="cleanup.sort_members" value="true"/>
|
||||
<setting id="cleanup.insert_inferred_type_arguments" value="false"/>
|
||||
<setting id="cleanup.add_missing_override_annotations" value="true"/>
|
||||
<setting id="cleanup.system_property_line_separator" value="false"/>
|
||||
<setting id="cleanup.static_inner_class" value="false"/>
|
||||
<setting id="cleanup.use_directly_map_method" value="false"/>
|
||||
<setting id="cleanup.add_all" value="false"/>
|
||||
<setting id="cleanup.convert_to_enhanced_for_loop" value="false"/>
|
||||
<setting id="cleanup.single_used_field" value="false"/>
|
||||
<setting id="cleanup.collection_cloning" value="false"/>
|
||||
<setting id="cleanup.comparing_on_criteria" value="false"/>
|
||||
<setting id="cleanup.stringbuffer_to_stringbuilder" value="false"/>
|
||||
<setting id="cleanup.do_while_rather_than_while" value="true"/>
|
||||
<setting id="cleanup.remove_unused_private_types" value="false"/>
|
||||
<setting id="cleanup.make_variable_declarations_final" value="false"/>
|
||||
<setting id="cleanup.merge_conditional_blocks" value="false"/>
|
||||
<setting id="cleanup.never_use_parentheses_in_expressions" value="true"/>
|
||||
<setting id="cleanup.use_blocks" value="false"/>
|
||||
<setting id="cleanup.array_with_curly" value="false"/>
|
||||
<setting id="cleanup.remove_unnecessary_array_creation" value="false"/>
|
||||
<setting id="cleanup.add_missing_deprecated_annotations" value="true"/>
|
||||
<setting id="cleanup.operand_factorization" value="false"/>
|
||||
<setting id="cleanup.qualify_static_method_accesses_with_declaring_class" value="false"/>
|
||||
<setting id="cleanup.remove_trailing_whitespaces_all" value="true"/>
|
||||
<setting id="cleanup.convert_to_switch_expressions" value="false"/>
|
||||
<setting id="cleanup.remove_redundant_type_arguments" value="false"/>
|
||||
<setting id="cleanup.number_suffix" value="false"/>
|
||||
<setting id="cleanup.redundant_comparator" value="false"/>
|
||||
<setting id="cleanup.remove_unused_private_members" value="false"/>
|
||||
<setting id="cleanup.never_use_blocks" value="false"/>
|
||||
<setting id="cleanup.organize_imports" value="true"/>
|
||||
<setting id="cleanup.switch" value="false"/>
|
||||
<setting id="cleanup.stringbuilder_for_local_vars" value="false"/>
|
||||
<setting id="cleanup.make_parameters_final" value="false"/>
|
||||
<setting id="cleanup.ternary_operator" value="false"/>
|
||||
<setting id="cleanup.controlflow_merge" value="false"/>
|
||||
<setting id="cleanup.unreachable_block" value="false"/>
|
||||
<setting id="cleanup.always_use_blocks" value="true"/>
|
||||
<setting id="cleanup.add_serial_version_id" value="false"/>
|
||||
<setting id="cleanup.stringconcat_to_textblock" value="false"/>
|
||||
<setting id="cleanup.invert_equals" value="false"/>
|
||||
<setting id="cleanup.use_string_is_blank" value="false"/>
|
||||
<setting id="cleanup.remove_unused_local_variables" value="false"/>
|
||||
<setting id="cleanup.remove_redundant_modifiers" value="false"/>
|
||||
<setting id="cleanup.system_property_file_encoding" value="false"/>
|
||||
<setting id="cleanup.sort_members_all" value="false"/>
|
||||
<setting id="cleanup.double_negation" value="false"/>
|
||||
<setting id="cleanup.format_source_code_changes_only" value="false"/>
|
||||
<setting id="cleanup.arrays_fill" value="false"/>
|
||||
<setting id="cleanup.add_generated_serial_version_id" value="false"/>
|
||||
<setting id="cleanup.plain_replacement" value="false"/>
|
||||
<setting id="cleanup.precompile_regex" value="false"/>
|
||||
<setting id="cleanup.useless_return" value="false"/>
|
||||
<setting id="cleanup.simplify_lambda_expression_and_method_ref" value="false"/>
|
||||
<setting id="cleanup.unlooped_while" value="false"/>
|
||||
<setting id="cleanup.make_local_variable_final" value="false"/>
|
||||
<setting id="cleanup.pull_up_assignment" value="false"/>
|
||||
<setting id="cleanup.overridden_assignment" value="false"/>
|
||||
<setting id="cleanup.else_if" value="false"/>
|
||||
<setting id="cleanup.reduce_indentation" value="false"/>
|
||||
<setting id="cleanup.use_this_for_non_static_method_access" value="false"/>
|
||||
<setting id="cleanup.use_this_for_non_static_field_access" value="false"/>
|
||||
<setting id="cleanup.use_this_for_non_static_field_access_only_if_necessary" value="true"/>
|
||||
<setting id="cleanup.hash" value="false"/>
|
||||
<setting id="cleanup.boolean_literal" value="false"/>
|
||||
<setting id="cleanup.add_default_serial_version_id" value="true"/>
|
||||
<setting id="cleanup.add_missing_methods" value="false"/>
|
||||
<setting id="cleanup.primitive_comparison" value="false"/>
|
||||
<setting id="cleanup.one_if_rather_than_duplicate_blocks_that_fall_through" value="false"/>
|
||||
</profile>
|
||||
</profiles>
|
Before Width: | Height: | Size: 488 B After Width: | Height: | Size: 450 B |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 886 B |
@ -24,4 +24,4 @@ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
--------------------------------------------------------------------------------
|
||||
--------------------------------------------------------------------------------
|
||||
|
@ -19,4 +19,4 @@
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
*/
|
||||
|
BIN
desktopRuntime/libEGL.so.1
Normal file
BIN
desktopRuntime/libGLESv2.so
Normal file
@ -18,4 +18,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
@ -4,4 +4,4 @@ Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
5
desktopRuntime/resources/EPKVersionIdentifier.txt
Normal file
@ -0,0 +1,5 @@
|
||||
<<<<<<< Updated upstream
|
||||
0.4.2
|
||||
=======
|
||||
0.4.2
|
||||
>>>>>>> Stashed changes
|
41
desktopRuntime/resources/ES6ShimScript.txt
Normal file
@ -0,0 +1,41 @@
|
||||
(function(_jsGlobal){try {(function(){var namedFunction=function(name,body){if(typeof body==="function"){try {Object.defineProperty(body,"name",{configurable:true,enumerable:false,writable:false,value:name});}catch(ex){}}return body;};var enabledShims=[];var collectionsShimImpl=function(){var i;var createCollection=function(proto,objectOnly){var Collection=namedFunction("Collection",function(a){if(!this||this.constructor!==Collection)return new Collection(a);Object.defineProperty(this,
|
||||
"_keys",{value:[]});Object.defineProperty(this,"_values",{value:[]});Object.defineProperty(this,"_itp",{value:[]});Object.defineProperty(this,"objectOnly",{value:objectOnly});if(a)init.call(this,a);});if(!objectOnly){Object.defineProperty(proto,"size",{get:sharedSize});}proto.constructor=Collection;for(var k in proto){Object.defineProperty(Collection.prototype,k,{value:proto[k]});}return Collection;};var init=function(a){if(this.add)a.forEach(this.add,this);else a.forEach(function(a){this.set(a[0],a[1]);},this);};var sharedDelete
|
||||
=function(key){if(this.has(key)){this._keys.splice(i,1);this._values.splice(i,1);this._itp.forEach(function(p){if(i<p[0])p[0]--;});}return -1<i;};var sharedGet=namedFunction("get",function(key){return this.has(key)?this._values[i]:$rt_globals.undefined;});var has=namedFunction("has",function(list,key){if(this.objectOnly&&key!==Object(key))throw new $rt_globals.TypeError("Invalid value used as weak collection key");if(key!=key||key===0)for(i=list.length;i--&&!$rt_globals.is(list[i],key);){}else i=list.indexOf(key);return -1
|
||||
<i;});var setHas=namedFunction("has",function(value){return has.call(this,this._values,value);});var mapHas=namedFunction("has",function(value){return has.call(this,this._keys,value);});var sharedSet=namedFunction("set",function(key,value){this.has(key)?(this._values[i]=value):(this._values[this._keys.push(key) -1]=value);return this;});var sharedAdd=namedFunction("add",function(value){if(!this.has(value))this._values.push(value);return this;});var sharedClear=namedFunction("clear",function(){(this._keys||0).length
|
||||
=this._values.length=0;});var sharedKeys=namedFunction("keys",function(){return sharedIterator(this._itp,this._keys);});var sharedValues=namedFunction("values",function(){return sharedIterator(this._itp,this._values);});var mapEntries=namedFunction("entries",function(){return sharedIterator(this._itp,this._keys,this._values);});var setEntries=namedFunction("entries",function(){return sharedIterator(this._itp,this._values,this._values);});var sharedIterator=function(itp,array,array2){var p=[0],done=false;itp.push(p);return {
|
||||
next:function(){var v,k=p[0];if(!done&&k<array.length){v=array2?[array[k],array2[k]]:array[k];p[0]++;}else {done=true;itp.splice(itp.indexOf(p),1);}return {done:done,value:v};}};};var sharedSize=namedFunction("size",function(){return this._values.length;});var sharedForEach=namedFunction("forEach",function(callback,context){var it=this.entries();for(;;){var r=it.next();if(r.done)break;callback.call(context,r.value[1],r.value[0],this);}});return {createCollection:createCollection,init:init,sharedDelete:sharedDelete,
|
||||
sharedGet:sharedGet,has:has,setHas:setHas,mapHas:mapHas,sharedSet:sharedSet,sharedAdd:sharedAdd,sharedClear:sharedClear,sharedKeys:sharedKeys,sharedValues:sharedValues,mapEntries:mapEntries,setEntries:setEntries,sharedIterator:sharedIterator,sharedSize:sharedSize,sharedForEach:sharedForEach};}();var shim_Map=function(){if(typeof $rt_globals.Map==="undefined"||typeof (new $rt_globals.Map()).values!=="function"||!((new $rt_globals.Map()).values()).next){Object.defineProperty(_jsGlobal,"Map",{value:namedFunction("Map",
|
||||
collectionsShimImpl.createCollection({'delete':collectionsShimImpl.sharedDelete,has:collectionsShimImpl.mapHas,get:collectionsShimImpl.sharedGet,set:collectionsShimImpl.sharedSet,keys:collectionsShimImpl.sharedKeys,values:collectionsShimImpl.sharedValues,entries:collectionsShimImpl.mapEntries,forEach:collectionsShimImpl.sharedForEach,clear:collectionsShimImpl.sharedClear}))});return true;}else {return false;}};var shim_WeakMap=function(){if(typeof $rt_globals.WeakMap==="undefined"){Object.defineProperty(_jsGlobal,
|
||||
"WeakMap",{value:namedFunction("WeakMap",collectionsShimImpl.createCollection({'delete':collectionsShimImpl.sharedDelete,clear:collectionsShimImpl.sharedClear,get:collectionsShimImpl.sharedGet,has:collectionsShimImpl.mapHas,set:collectionsShimImpl.sharedSet}))});return true;}else {return false;}};var shim_Set=function(){if(typeof $rt_globals.Set==="undefined"||typeof (new $rt_globals.Set()).values!=="function"||!((new $rt_globals.Set()).values()).next){Object.defineProperty(_jsGlobal,"Set",{value:namedFunction("Set",
|
||||
collectionsShimImpl.createCollection({has:collectionsShimImpl.setHas,add:collectionsShimImpl.sharedAdd,'delete':collectionsShimImpl.sharedDelete,clear:collectionsShimImpl.sharedClear,keys:collectionsShimImpl.sharedValues,values:collectionsShimImpl.sharedValues,entries:collectionsShimImpl.setEntries,forEach:collectionsShimImpl.sharedForEach}))});return true;}else {return false;}};var shim_WeakSet=function(){if(typeof $rt_globals.WeakSet==="undefined"){Object.defineProperty(_jsGlobal,"WeakSet",{value:namedFunction("WeakSet",
|
||||
collectionsShimImpl.createCollection({'delete':collectionsShimImpl.sharedDelete,add:collectionsShimImpl.sharedAdd,clear:collectionsShimImpl.sharedClear,has:collectionsShimImpl.setHas}))});return true;}else {return false;}};var createPromiseShim=function(){var PROMISE_ID="[["+(($rt_globals.Math.random()).toString(36)).substring(2)+"]]";var PENDING=void 0;var FULFILLED=1;var REJECTED=2;var _qlen=0;var msgChannel=null;var useLegacyFlush=false;var isFlushTest=false;var queue=new $rt_globals.Array(1000);var _noop
|
||||
=function(){};var _initMessageChannelFlush=function(flushFunc){if(typeof $rt_globals.MessageChannel==="undefined"){useLegacyFlush=true;$rt_globals.setTimeout(flushFunc,0);return;}isFlushTest=true;try {msgChannel=new $rt_globals.MessageChannel();var testVal=false;var _flushTest=function(){testVal=true;};msgChannel.port1.addEventListener("message",_flushTest);msgChannel.port1.start();msgChannel.port2.start();msgChannel.port2.postMessage("");if(testVal){msgChannel=null;useLegacyFlush=true;isFlushTest=false;$rt_globals.setTimeout(flushFunc,
|
||||
0);return;}$rt_globals.setTimeout(function(){msgChannel.port1.removeEventListener("message",_flushTest);if(!testVal){msgChannel=null;useLegacyFlush=true;}else {msgChannel.port1.addEventListener("message",flushFunc);}isFlushTest=false;flushFunc();},10);}catch(ex){msgChannel=null;useLegacyFlush=true;isFlushTest=false;$rt_globals.setTimeout(flushFunc,0);return;}};var _scheduleFlush=function(){if(useLegacyFlush||isFlushTest){$rt_globals.setTimeout(_flush,0);}else {if(msgChannel===null){_initMessageChannelFlush(_flush);return;}msgChannel.port2.postMessage("");}};var _flush
|
||||
=function(){for(var i=0;i<_qlen;i+=2){var callback=queue[i];var arg=queue[i+1];callback(arg);queue[i]=$rt_globals.undefined;queue[i+1]=$rt_globals.undefined;}_qlen=0;};var _asap=function(callback,arg){queue[_qlen]=callback;queue[_qlen+1]=arg;_qlen+=2;if(_qlen===2){_scheduleFlush();}};var _handleForeignThenable=function(promise,thenable,then$$1){_asap(function(promise){var sealed=false;var error=_tryThen(then$$1,thenable,function(value){if(sealed){return;}sealed=true;if(thenable!==value){__resolve(promise,value);}
|
||||
else {_fulfill(promise,value);}},function(reason){if(sealed){return;}sealed=true;_reject(promise,reason);},"Settle: "+(promise._label||" unknown promise"));if(!sealed&&error){sealed=true;_reject(promise,error);}},promise);};var _tryThen=function(then$$1,value,fulfillmentHandler,rejectionHandler){try {then$$1.call(value,fulfillmentHandler,rejectionHandler);}catch(e){return e;}};var _handleOwnThenable=function(promise,thenable){if(thenable._state===FULFILLED){_fulfill(promise,thenable._result);}else if(thenable._state
|
||||
===REJECTED){_reject(promise,thenable._result);}else {_subscribe(thenable,$rt_globals.undefined,function(value){return __resolve(promise,value);},function(reason){return _reject(promise,reason);});}};var _handleMaybeThenable=function(promise,maybeThenable,then$$1){if(maybeThenable.constructor===promise.constructor&&then$$1===_then&&maybeThenable.constructor.resolve===_resolve){_handleOwnThenable(promise,maybeThenable);}else {if(then$$1===$rt_globals.undefined){_fulfill(promise,maybeThenable);}else if(typeof then$$1
|
||||
==="function"){_handleForeignThenable(promise,maybeThenable,then$$1);}else {_fulfill(promise,maybeThenable);}}};var __resolve=function(promise,value){if(promise===value){_reject(promise,new $rt_globals.TypeError("You cannot resolve a promise with itself"));}else if(typeof value==="object"||typeof value==="function"){var then$$1=void 0;try {then$$1=value.then;}catch(error){_reject(promise,error);return;}_handleMaybeThenable(promise,value,then$$1);}else {_fulfill(promise,value);}};var _reject=function(promise,
|
||||
reason){if(promise._state!==PENDING){return;}promise._state=REJECTED;promise._result=reason;_asap(_publishRejection,promise);};var _subscribe=function(parent,child,onFulfillment,onRejection){var _subscribers=parent._subscribers;var length=_subscribers.length;parent._onerror=null;_subscribers[length]=child;_subscribers[length+FULFILLED]=onFulfillment;_subscribers[length+REJECTED]=onRejection;if(length===0&&parent._state){_asap(_publish,parent);}};var _publish=function(promise){var subscribers=promise._subscribers;var settled
|
||||
=promise._state;if(subscribers.length===0){return;}var child=void 0,callback=void 0,detail=promise._result;for(var i=0;i<subscribers.length;i+=3){child=subscribers[i];callback=subscribers[i+settled];if(child){_invokeCallback(settled,child,callback,detail);}else {callback(detail);}}promise._subscribers.length=0;};var _publishRejection=function(promise){if(promise._onerror){promise._onerror(promise._result);}_publish(promise);};var _fulfill=function(promise,value){if(promise._state!==PENDING){return;}promise._result
|
||||
=value;promise._state=FULFILLED;if(promise._subscribers.length!==0){_asap(_publish,promise);}};var _invokeCallback=function(settled,promise,callback,detail){var hasCallback=typeof callback==="function",value=void 0,error=void 0,succeeded=true;if(hasCallback){try {value=callback(detail);}catch(e){succeeded=false;error=e;}if(promise===value){_reject(promise,new $rt_globals.TypeError("A promises callback cannot return that same promise."));return;}}else {value=detail;}if(promise._state!==PENDING){}else if(hasCallback
|
||||
&&succeeded){__resolve(promise,value);}else if(succeeded===false){_reject(promise,error);}else if(settled===FULFILLED){_fulfill(promise,value);}else if(settled===REJECTED){_reject(promise,value);}};var _initializePromise=function(promise,resolver){try {resolver(function(value){__resolve(promise,value);},function(reason){_reject(promise,reason);});}catch(e){_reject(promise,e);}};var id=0;var _nextId=function(){return id++;};var _makePromise=function(promise){promise[PROMISE_ID]=id++;promise._state=$rt_globals.undefined;promise._result
|
||||
=$rt_globals.undefined;promise._subscribers=[];};var Promise;Promise=namedFunction("Promise",function(resolver){this[PROMISE_ID]=_nextId();this._result=this._state=$rt_globals.undefined;this._subscribers=[];if(_noop!==resolver){typeof resolver!=='function'&&$rt_globals._needsResolver();this instanceof Promise?_initializePromise(this,resolver):$rt_globals._needsNew();}});var _then=namedFunction("then",function(onFulfillment,onRejection){var parent=this;var child=new this.constructor(_noop);if(child[PROMISE_ID]
|
||||
===$rt_globals.undefined){_makePromise(child);}var _state=parent._state;if(_state){var callback=arguments[_state -1];_asap(function(){return _invokeCallback(_state,child,callback,parent._result);});}else {_subscribe(parent,child,onFulfillment,onRejection);}return child;});Promise.prototype.then=_then;Promise.prototype.catch=namedFunction("catch",function(onRejection){return this.then(null,onRejection);});Promise.prototype.finally=namedFunction("finally",function(callback){var promise=this;var constructor=promise.constructor;if
|
||||
(typeof callback==="function"){return promise.then(function(value){return (constructor.resolve(callback())).then(function(){return value;});},function(reason){return (constructor.resolve(callback())).then(function(){throw reason;});});}return promise.then(callback,callback);});Promise.all=namedFunction("all",function(entries){throw new $rt_globals.Error("Promise.all is not included in the ES6 compatibility shim!");});Promise.race=namedFunction("race",function(entries){var Constructor=this;if(!$rt_globals.Array.isArray(entries))
|
||||
{return new Constructor(function(_,reject){return reject(new $rt_globals.TypeError("You must pass an array to race."));});}else {return new Constructor(function(resolve,reject){var length=entries.length;for(var i=0;i<length;i++){(Constructor.resolve(entries[i])).then(resolve,reject);}});}});var _resolve=namedFunction("resolve",function(object){var Constructor=this;if(object&&typeof object==="object"&&object.constructor===Constructor){return object;}var promise=new Constructor(_noop);__resolve(promise,object);return promise;});Promise.resolve
|
||||
=_resolve;Promise.reject=namedFunction("reject",function(reason){var Constructor=this;var promise=new Constructor(_noop);_reject(promise,reason);return promise;});return Promise;};var shim_Promise=function(){if(typeof Promise==="undefined"){Object.defineProperty(_jsGlobal,"Promise",{value:createPromiseShim()});return true;}else {return false;}};var shim_String_fromCodePoint=function(){if(typeof $rt_globals.String.fromCodePoint==="undefined"){Object.defineProperty($rt_globals.String,"fromCodePoint",{value:namedFunction("fromCodePoint",
|
||||
function(codePoints){var result=[];var next;for(var i=0,length=arguments.length;i<length;i++){next=$rt_globals.Number(arguments[i]);if(next!==(next|0)||next<0||next>0x10FFFF){throw new $rt_globals.RangeError("Invalid code point "+next);}if(next<0x10000){result.push($rt_globals.String.fromCharCode(next));}else {next -=0x10000;result.push($rt_globals.String.fromCharCode((next>>10)+0xD800));result.push($rt_globals.String.fromCharCode(next%0x400+0xDC00));}}return result.join("");})});return true;}else {return false;}};var shim_String_proto_codePointAt
|
||||
=function(){if(typeof $rt_globals.String.prototype.codePointAt==="undefined"){Object.defineProperty($rt_globals.String.prototype,"codePointAt",{value:namedFunction("codePointAt",function(pos){pos=pos|0;var leng=this.length;if(pos>=0&&pos<leng){var first=this.charCodeAt(pos);var isEnd=pos+1===leng;if(first<0xD800||first>0xDBFF||isEnd){return first;}var second=this.charCodeAt(pos+1);if(second<0xDC00||second>0xDFFF){return first;}return (first -0xD800)*1024+second -0xDC00+0x10000;}})});return true;}else {return false;}};var shim_String_proto_startsWith
|
||||
=function(){if(typeof $rt_globals.String.prototype.startsWith==="undefined"){Object.defineProperty($rt_globals.String.prototype,"startsWith",{value:namedFunction("startsWith",function(str){var position=0;if(arguments.length>1){position=arguments[1];}var start=$rt_globals.Math.max(position,0)|0;return this.slice(start,start+str.length)===str;})});return true;}else {return false;}};var shim_String_proto_endsWith=function(){if(typeof $rt_globals.String.prototype.endsWith==="undefined"){Object.defineProperty($rt_globals.String.prototype,
|
||||
"endsWith",{value:namedFunction("endsWith",function(str){var len=this.length;var endPosition;if(arguments.length>1){endPosition=arguments[1];}var pos=typeof endPosition==="undefined"?len:endPosition|0;var end=$rt_globals.Math.min($rt_globals.Math.max(pos,0)|0,len);return this.slice(end -str.length,end)===str;})});return true;}else {return false;}};var shim_String_proto_includes=function(){if(typeof $rt_globals.String.prototype.includes==="undefined"){Object.defineProperty($rt_globals.String.prototype,"includes",
|
||||
{value:namedFunction("includes",function(str){var position;if(arguments.length>1){position=arguments[1];}return this.indexOf(str,position)!== -1;})});return true;}else {return false;}};var stringRepeatHelper;stringRepeatHelper=function(s,times){if(times<1){return '';}if(times%2){return stringRepeatHelper(s,times -1)+s;}var half=stringRepeatHelper(s,times/2);return half+half;};var shim_String_proto_repeat=function(){if(typeof $rt_globals.String.prototype.repeat==="undefined"){Object.defineProperty($rt_globals.String.prototype,
|
||||
"repeat",{value:namedFunction("repeat",function(numTimes){if(numTimes>=$rt_globals.Infinity||(numTimes|=0)<0){throw new $rt_globals.RangeError("repeat count must be less than infinity and not overflow maximum string size");}return stringRepeatHelper(this,numTimes);})});return true;}else {return false;}};var shim_Object_is=function(){if(typeof Object.is==="undefined"){Object.defineProperty(Object,"is",{value:namedFunction("is",function(a,b){return a===b||a!==a&&b!==b;})});return true;}else {return false;}};var shim_Object_setPrototypeOf
|
||||
=function(){if(typeof Object.setPrototypeOf==="undefined"){var theShim=function(Object,magic){var set;var checkArgs=function(O,proto){if(typeof O!=="object"||O===null){throw new $rt_globals.TypeError("can not set prototype on a non-object");}if(typeof proto!=="object"&&proto!==null){throw new $rt_globals.TypeError("can only set prototype to an object or null");}};var setPrototypeOf=function(O,proto){checkArgs(O,proto);set.call(O,proto);return O;};try {set=(Object.getOwnPropertyDescriptor(Object.prototype,magic)).set;set.call({
|
||||
},null);}catch(o_O){if(Object.prototype!=={}[magic]||{__proto__:null}.__proto__===void 0){$rt_globals.console.error("ES6Shims: Can not shim Object.setPrototypeOf on this browser! Ignoring for now");return false;}set=function(proto){this[magic]=proto;};}return setPrototypeOf;}(Object,"__proto__");if(theShim){Object.defineProperty(Object,"setPrototypeOf",{value:namedFunction("setPrototypeOf",theShim)});return true;}else {return false;}}else {return false;}};var shim_Function_proto_name=function(){if($rt_globals.Math.max.name
|
||||
!=="max"){Object.defineProperty($rt_globals.Function.prototype,"name",{configurable:true,enumerable:false,get:function(){if(this===$rt_globals.Function.prototype){return "";}var str=$rt_globals.Function.prototype.toString.call(this);var match=str.match(/\s*function\s+([^(\s]*)\s*/);var name=match&&match[1];Object.defineProperty(this,"name",{configurable:true,enumerable:false,writable:false,value:name});return name;}});return true;}else {return false;}};var shim_Math_sign=function(){if(typeof $rt_globals.Math.sign
|
||||
==="undefined"){Object.defineProperty($rt_globals.Math,"sign",{value:namedFunction("sign",function(val){var number=$rt_globals.Number(val);if(number===0){return number;}if($rt_globals.isNaN(number)){return number;}return number<0? -1:1;})});return true;}else {return false;}};var shim_Symbol=function(){if(typeof $rt_globals.Symbol==="undefined"){Object.defineProperty(_jsGlobal,"Symbol",{value:function(){var symRet=namedFunction("Symbol",function(){return "[[ShimbolR_"+(($rt_globals.Math.random()).toString(36)).substring(2)
|
||||
+"]]";});symRet.for=namedFunction("for",function(symName){if(!(typeof symName==="string"))return $rt_globals.undefined;return "[[ShimbolN_"+symName+"]]";});symRet.keyFor=namedFunction("keyFor",function(sym){return typeof sym==="string"&&sym.startsWith("[[ShimbolN_")&&sym.endsWith("]]")?sym.substring(11,sym.length -2):$rt_globals.undefined;});return symRet;}()});return true;}else {return false;}};var hasErrors=false;var shim_install=function(str,cb){try {return cb();}catch(_exx_){hasErrors=true;$rt_globals.console.error("ES6Shims: Failed to detect and enable shim \""
|
||||
+str+"\" for this browser! (Continuing anyway)");$rt_globals.console.error(_exx_);return false;}};if(shim_install("Map",shim_Map))enabledShims.push(0);if(shim_install("WeakMap",shim_WeakMap))enabledShims.push(1);if(shim_install("Set",shim_Set))enabledShims.push(2);if(shim_install("WeakSet",shim_WeakSet))enabledShims.push(3);if(shim_install("Promise",shim_Promise))enabledShims.push(4);if(shim_install("String_fromCodePoint",shim_String_fromCodePoint))enabledShims.push(5);if(shim_install("String_proto_codePointAt",
|
||||
shim_String_proto_codePointAt))enabledShims.push(6);if(shim_install("String_proto_startsWith",shim_String_proto_startsWith))enabledShims.push(7);if(shim_install("String_proto_endsWith",shim_String_proto_endsWith))enabledShims.push(8);if(shim_install("String_proto_includes",shim_String_proto_includes))enabledShims.push(9);if(shim_install("String_proto_repeat",shim_String_proto_repeat))enabledShims.push(10);if(shim_install("Object_is",shim_Object_is))enabledShims.push(12);if(shim_install("Object_setPrototypeOf",
|
||||
shim_Object_setPrototypeOf))enabledShims.push(13);if(shim_install("Function_proto_name",shim_Function_proto_name))enabledShims.push(14);if(shim_install("Math_sign",shim_Math_sign))enabledShims.push(15);if(shim_install("Symbol",shim_Symbol))enabledShims.push(16);var enCnt=enabledShims.length;_jsGlobal.__eaglercraftXES6ShimStatus={getShimInitStatus:function(){return (enCnt>0?1:0)|(hasErrors?2:0);},getEnabledShimCount:function(){return enCnt;},getEnabledShimID:function(idxIn){return enabledShims[idxIn];}};})();}
|
||||
catch(_ex_){$rt_globals.console.error("ES6Shims: Failed to detect and enable shims for this browser! (Continuing anyway)");$rt_globals.console.error(_ex_);_jsGlobal.__eaglercraftXES6ShimStatus={getShimInitStatus:function(){return -1;},getEnabledShimCount:function(){return 0;},getEnabledShimID:function(idxIn){return $rt_globals.undefined;}};}})($rt_globals);
|
189
desktopRuntime/resources/OfflineDownloadTemplate.txt
Normal file
1
desktopRuntime/resources/UpdateDownloadSources.txt
Normal file
@ -0,0 +1 @@
|
||||
url: https://starlike.orionzleon.me/latest_update.dat
|
@ -1,4 +1,20 @@
|
||||
|
||||
Starlike Client
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- SpeedSlicer - Owner
|
||||
- zumbiepig - Co-Owner
|
||||
- CatFoolYou - Texture artist
|
||||
- Oeil-de-Lynx - Contributor
|
||||
|
||||
HoosierTransfer's Dedicated Section
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
HoosierTransfer:
|
||||
- Made the culling mod for this
|
||||
- Helped out in early dev stages
|
||||
- Made the VERY first eagler mod (1.9)
|
||||
- Cool Person
|
||||
|
||||
EaglercraftX Developers
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@ -34,6 +50,13 @@
|
||||
Code used within EaglercraftX
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Other Helpers
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- Cirs?? - Wiki Contributor
|
||||
- A_Person - Boosted the server seven times :)
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
Project Name: TeaVM
|
||||
@ -217,6 +240,80 @@
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
Project Name: High Performance Primitive Collections
|
||||
Project Author: Carrot Search
|
||||
Project URL: http://labs.carrotsearch.com/hppc.html
|
||||
|
||||
Used For: Primitive collections library for the client
|
||||
|
||||
* Copyright 2010-2013, Carrot Search s.c., Boznicza 11/56, Poznan, Poland
|
||||
*
|
||||
* 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.
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
Project Name: Alfheim
|
||||
Project Author: Red Studio
|
||||
Project URL: https://github.com/Red-Studio-Ragnarok/Alfheim
|
||||
|
||||
Used For: Optimized lighting engine
|
||||
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2023 Red Studio
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
Project Name: OptiFine (1.8.9_HD_U_M6)
|
||||
Project Author: sp614x
|
||||
Project URL: https://optifine.net/
|
||||
|
||||
Used For: A few, limited portions we "borrowed" without the author's permission
|
||||
|
||||
Note: Eaglercraft is not OptiFine, we only use the code for connected textures
|
||||
and maintaining compatibility with certain resource pack features
|
||||
|
||||
* The mod OptiFine is Copyright © 2011-2021 by sp614x and the intellectual
|
||||
* property of the author.
|
||||
* It may be not be reproduced under any circumstances except for personal,
|
||||
* private use as long as it remains in its unaltered, unedited form.
|
||||
* It may not be placed on any web site or otherwise distributed publicly
|
||||
* without advance written permission.
|
||||
* Use of this mod on any other website or as a part of any public display
|
||||
* is strictly prohibited and a violation of copyright.
|
||||
|
||||
(sorry sp614x)
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
Project Name: Google Guava
|
||||
Project Author: Google
|
||||
Project URL: https://github.com/google/guava
|
||||
@ -514,6 +611,45 @@
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
Project Name: OpenJDK
|
||||
Project Author: Oracle, IBM
|
||||
Project URL: https://openjdk.org/projects/jdk/17/
|
||||
|
||||
Used For: Debloated version of IBM's ICU4J for reordering Arabic and Hebrew text
|
||||
|
||||
* Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
|
||||
* (C) Copyright IBM Corp. 1999-2003 - All Rights Reserved
|
||||
*
|
||||
* The original version of this source code and documentation is
|
||||
* copyrighted and owned by IBM. These materials are provided
|
||||
* under terms of a License Agreement between IBM and Sun.
|
||||
* This technology is protected by multiple US and International
|
||||
* patents. This notice and attribution to IBM may not be removed.
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
Project Name: Java-WebSocket
|
||||
Project Author: Nathan Rajlich (TooTallNate)
|
||||
Project URL: http://tootallnate.github.io/Java-WebSocket
|
||||
@ -785,3 +921,78 @@
|
||||
* THE SOFTWARE.
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
Project Name: Emscripten
|
||||
Project Author: Emscripten authors
|
||||
Project URL: https://emscripten.org/
|
||||
|
||||
Used For: Compiling the WASM runtime's loader.wasm program
|
||||
|
||||
* Emscripten is available under 2 licenses, the MIT license and the
|
||||
* University of Illinois/NCSA Open Source License.
|
||||
*
|
||||
* Copyright (c) 2010-2014 Emscripten authors, see AUTHORS file.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
Project Name: XZ Embedded
|
||||
Project Author: Lasse Collin (Larhzu)
|
||||
Project URL: https://tukaani.org/xz/embedded.html
|
||||
|
||||
Used For: Decompressing the WASM runtime
|
||||
|
||||
* Copyright (C) The XZ Embedded authors and contributors
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this
|
||||
* software for any purpose with or without fee is hereby granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
|
||||
* THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
Project Name: XZ for Java
|
||||
Project Author: Lasse Collin (Larhzu)
|
||||
Project URL: https://tukaani.org/xz/java.html
|
||||
|
||||
Used For: Compression in the MakeWASMClientBundle command
|
||||
|
||||
* Copyright (C) The XZ for Java authors and contributors
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this
|
||||
* software for any purpose with or without fee is hereby granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
|
||||
* THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
@ -30,7 +30,6 @@
|
||||
<option class="_eaglercraftX_boot_menu_launch_conf_val_launch_type_opt" value="PEYTON_V1">PeytonPlayz585 Indev</option>
|
||||
<option class="_eaglercraftX_boot_menu_launch_conf_val_launch_type_opt" value="PEYTON_V2">PeytonPlayz585 Alpha/Beta</option>
|
||||
<option class="_eaglercraftX_boot_menu_launch_conf_val_launch_type_opt" value="STANDARD_OFFLINE_V1">Standard Offline</option>
|
||||
<option class="_eaglercraftX_boot_menu_launch_conf_val_launch_type_opt" value="IFRAME_SANDBOX_V1">IFrame HTML File</option>
|
||||
</select>
|
||||
</p>
|
||||
</div>
|
||||
@ -85,4 +84,4 @@
|
||||
<p class="_eaglercraftX_boot_menu_footer_text _eaglercraftX_boot_menu_footer_text_boot_order" style="display:none;">Use the ↑ and ↓ keys to select which entry is highlighted.<br>Press CTRL+↑ and CTRL+↓ to adjust item order, or ESC to cancel.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -325,4 +325,4 @@
|
||||
text-align: left;
|
||||
padding: 0px 0px 32px 64px;
|
||||
color: #CCCCCC;
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
{
|
||||
"client_launch_type": "EAGLERX_V1",
|
||||
"clear_cookies_before_launch": false
|
||||
}
|
||||
"client_launch_type": "EAGLERX_V1",
|
||||
"clear_cookies_before_launch": false
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
{
|
||||
"client_launch_type": "EAGLERX_SIGNED_V1",
|
||||
"clear_cookies_before_launch": false
|
||||
}
|
||||
"client_launch_type": "EAGLERX_SIGNED_V1",
|
||||
"clear_cookies_before_launch": false
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
{
|
||||
"client_launch_type": "EAGLER_1_5_V2",
|
||||
"clear_cookies_before_launch": false
|
||||
}
|
||||
"client_launch_type": "EAGLER_1_5_V2",
|
||||
"clear_cookies_before_launch": false
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"client_launch_type": "EAGLER_1_5_V1",
|
||||
"join_server": "",
|
||||
"clear_cookies_before_launch": false
|
||||
}
|
||||
"client_launch_type": "EAGLER_1_5_V1",
|
||||
"join_server": "",
|
||||
"clear_cookies_before_launch": false
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"client_launch_type": "EAGLER_BETA_V1",
|
||||
"join_server": "",
|
||||
"clear_cookies_before_launch": false
|
||||
}
|
||||
"client_launch_type": "EAGLER_BETA_V1",
|
||||
"join_server": "",
|
||||
"clear_cookies_before_launch": false
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
{
|
||||
"client_launch_type": "PEYTON_V2",
|
||||
"clear_cookies_before_launch": false
|
||||
}
|
||||
"client_launch_type": "PEYTON_V2",
|
||||
"clear_cookies_before_launch": false
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
{
|
||||
"client_launch_type": "PEYTON_V2",
|
||||
"clear_cookies_before_launch": false
|
||||
}
|
||||
"client_launch_type": "PEYTON_V2",
|
||||
"clear_cookies_before_launch": false
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
{
|
||||
"client_launch_type": "PEYTON_V1",
|
||||
"clear_cookies_before_launch": false
|
||||
}
|
||||
"client_launch_type": "PEYTON_V1",
|
||||
"clear_cookies_before_launch": false
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
{
|
||||
"client_launch_type": "STANDARD_OFFLINE_V1",
|
||||
"client_launch_opts_var": "eaglercraftXOpts",
|
||||
"client_launch_opts_assetsURI_var": "assetsURI",
|
||||
"client_launch_opts_container_var": "container",
|
||||
"client_launch_main_func": "main",
|
||||
"clear_cookies_before_launch": false
|
||||
}
|
||||
"client_launch_type": "STANDARD_OFFLINE_V1",
|
||||
"client_launch_opts_var": "eaglercraftXOpts",
|
||||
"client_launch_opts_assetsURI_var": "assetsURI",
|
||||
"client_launch_opts_container_var": "container",
|
||||
"client_launch_main_func": "main",
|
||||
"clear_cookies_before_launch": false
|
||||
}
|
||||
|
@ -1,192 +1,108 @@
|
||||
{
|
||||
"defaults": {
|
||||
"EAGLERX_SIGNED_V1": {
|
||||
"conf": "conf_template_eaglercraftX_1_8_signed.json",
|
||||
"opts": "opts_template_eaglercraftX_1_8.txt"
|
||||
},
|
||||
"EAGLERX_V1": {
|
||||
"conf": "conf_template_eaglercraftX_1_8.json",
|
||||
"opts": "opts_template_eaglercraftX_1_8.txt"
|
||||
},
|
||||
"EAGLER_BETA_V1": {
|
||||
"conf": "conf_template_eaglercraft_b1_3.json",
|
||||
"opts": null
|
||||
},
|
||||
"EAGLER_1_5_V1": {
|
||||
"conf": "conf_template_eaglercraft_1_5_legacy.json",
|
||||
"opts": "opts_template_eaglercraft_1_5_legacy.txt"
|
||||
},
|
||||
"EAGLER_1_5_V2": {
|
||||
"conf": "conf_template_eaglercraft_1_5.json",
|
||||
"opts": "opts_template_eaglercraft_1_5.txt"
|
||||
},
|
||||
"PEYTON_V1": {
|
||||
"conf": "conf_template_peytonplayz585_indev.json",
|
||||
"opts": null
|
||||
},
|
||||
"PEYTON_V2": {
|
||||
"conf": "conf_template_peytonplayz585_a1_2_6.json",
|
||||
"opts": "opts_template_peytonplayz585_a1_2_6.txt"
|
||||
},
|
||||
"STANDARD_OFFLINE_V1": {
|
||||
"conf": "conf_template_standard_offline.json",
|
||||
"opts": null
|
||||
}
|
||||
},
|
||||
"templates": [
|
||||
{
|
||||
"name": "EaglercraftX 1.8",
|
||||
"conf": "conf_template_eaglercraftX_1_8.json",
|
||||
"opts": "opts_template_eaglercraftX_1_8.txt",
|
||||
"allow": [
|
||||
"EAGLER_STANDARD_OFFLINE"
|
||||
],
|
||||
"parseTypes": [
|
||||
"EAGLERCRAFTX_1_8_OFFLINE"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "EaglercraftX 1.8 Demo",
|
||||
"conf": "conf_template_eaglercraftX_1_8.json",
|
||||
"opts": "opts_template_eaglercraftX_1_8_demo.txt",
|
||||
"allow": [
|
||||
"EAGLER_STANDARD_OFFLINE"
|
||||
],
|
||||
"parseTypes": [
|
||||
"EAGLERCRAFTX_1_8_OFFLINE"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "EaglercraftX 1.8 HTML5 Cursors",
|
||||
"conf": "conf_template_eaglercraftX_1_8.json",
|
||||
"opts": "opts_template_eaglercraftX_1_8_html5Cursors.txt",
|
||||
"allow": [
|
||||
"EAGLER_STANDARD_OFFLINE"
|
||||
],
|
||||
"parseTypes": [
|
||||
"EAGLERCRAFTX_1_8_OFFLINE"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "EaglercraftX 1.8 Signed",
|
||||
"conf": "conf_template_eaglercraftX_1_8_signed.json",
|
||||
"opts": "opts_template_eaglercraftX_1_8.txt",
|
||||
"allow": [
|
||||
"EAGLER_SIGNED_OFFLINE"
|
||||
],
|
||||
"parseTypes": [
|
||||
"EAGLERCRAFTX_1_8_SIGNED"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "EaglercraftX 1.8 Signed Demo",
|
||||
"conf": "conf_template_eaglercraftX_1_8_signed.json",
|
||||
"opts": "opts_template_eaglercraftX_1_8_demo.txt",
|
||||
"allow": [
|
||||
"EAGLER_SIGNED_OFFLINE"
|
||||
],
|
||||
"parseTypes": [
|
||||
"EAGLERCRAFTX_1_8_SIGNED"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "EaglercraftX 1.8 Signed HTML5 Cursors",
|
||||
"conf": "conf_template_eaglercraftX_1_8_signed.json",
|
||||
"opts": "opts_template_eaglercraftX_1_8_html5Cursors.txt",
|
||||
"allow": [
|
||||
"EAGLER_SIGNED_OFFLINE"
|
||||
],
|
||||
"parseTypes": [
|
||||
"EAGLERCRAFTX_1_8_SIGNED"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Eaglercraft 1.5.2 (post-22w34a)",
|
||||
"conf": "conf_template_eaglercraft_1_5.json",
|
||||
"opts": "opts_template_eaglercraft_1_5.txt",
|
||||
"allow": [
|
||||
"EAGLER_STANDARD_1_5_OFFLINE"
|
||||
],
|
||||
"parseTypes": [
|
||||
"EAGLERCRAFT_1_5_NEW_OFFLINE"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Eaglercraft 1.5.2 Live Music (post-22w34a)",
|
||||
"conf": "conf_template_eaglercraft_1_5.json",
|
||||
"opts": "opts_template_eaglercraft_1_5_livestream.txt",
|
||||
"allow": [
|
||||
"EAGLER_STANDARD_1_5_OFFLINE"
|
||||
],
|
||||
"parseTypes": [
|
||||
"EAGLERCRAFT_1_5_NEW_OFFLINE"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Eaglercraft 1.5.2 (pre-22w34a)",
|
||||
"conf": "conf_template_eaglercraft_1_5_legacy.json",
|
||||
"opts": "opts_template_eaglercraft_1_5_legacy.txt",
|
||||
"allow": [
|
||||
"EAGLER_STANDARD_OFFLINE"
|
||||
],
|
||||
"parseTypes": [
|
||||
"EAGLERCRAFT_1_5_OLD_OFFLINE"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Eaglercraft Beta 1.3",
|
||||
"conf": "conf_template_eaglercraft_b1_3.json",
|
||||
"opts": null,
|
||||
"allow": [
|
||||
"EAGLER_STANDARD_OFFLINE"
|
||||
],
|
||||
"parseTypes": [
|
||||
"EAGLERCRAFT_BETA_B1_3_OFFLINE"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "PeytonPlayz585 Beta 1.7.3",
|
||||
"conf": "conf_template_peytonplayz585_b1_7_3.json",
|
||||
"opts": "opts_template_peytonplayz585_b1_7_3.txt",
|
||||
"allow": [
|
||||
"EAGLER_STANDARD_OFFLINE"
|
||||
],
|
||||
"parseTypes": [
|
||||
"PEYTONPLAYZ585_ALPHA_BETA"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "PeytonPlayz585 Alpha 1.2.6",
|
||||
"conf": "conf_template_peytonplayz585_a1_2_6.json",
|
||||
"opts": "opts_template_peytonplayz585_a1_2_6.txt",
|
||||
"allow": [
|
||||
"EAGLER_STANDARD_OFFLINE"
|
||||
],
|
||||
"parseTypes": [
|
||||
"PEYTONPLAYZ585_ALPHA_BETA"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "PeytonPlayz585 Indev",
|
||||
"conf": "conf_template_peytonplayz585_indev.json",
|
||||
"opts": null,
|
||||
"allow": [
|
||||
"EAGLER_STANDARD_OFFLINE"
|
||||
],
|
||||
"parseTypes": [
|
||||
"PEYTONPLAYZ585_INDEV"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Standard Offline Download",
|
||||
"conf": "conf_template_standard_offline.json",
|
||||
"opts": null,
|
||||
"allow": [
|
||||
"EAGLER_STANDARD_OFFLINE"
|
||||
],
|
||||
"parseTypes": [
|
||||
"EXPORTED_STANDARD_OFFLINE"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
"defaults": {
|
||||
"EAGLERX_SIGNED_V1": {
|
||||
"conf": "conf_template_eaglercraftX_1_8_signed.json",
|
||||
"opts": "opts_template_eaglercraftX_1_8.txt"
|
||||
},
|
||||
"EAGLERX_V1": {
|
||||
"conf": "conf_template_eaglercraftX_1_8.json",
|
||||
"opts": "opts_template_eaglercraftX_1_8.txt"
|
||||
},
|
||||
"EAGLER_BETA_V1": {
|
||||
"conf": "conf_template_eaglercraft_b1_3.json",
|
||||
"opts": null
|
||||
},
|
||||
"EAGLER_1_5_V1": {
|
||||
"conf": "conf_template_eaglercraft_1_5_legacy.json",
|
||||
"opts": "opts_template_eaglercraft_1_5_legacy.txt"
|
||||
},
|
||||
"EAGLER_1_5_V2": {
|
||||
"conf": "conf_template_eaglercraft_1_5.json",
|
||||
"opts": "opts_template_eaglercraft_1_5.txt"
|
||||
},
|
||||
"PEYTON_V1": {
|
||||
"conf": "conf_template_peytonplayz585_indev.json",
|
||||
"opts": null
|
||||
},
|
||||
"PEYTON_V2": {
|
||||
"conf": "conf_template_peytonplayz585_a1_2_6.json",
|
||||
"opts": "opts_template_peytonplayz585_a1_2_6.txt"
|
||||
},
|
||||
"STANDARD_OFFLINE_V1": {
|
||||
"conf": "conf_template_standard_offline.json",
|
||||
"opts": null
|
||||
}
|
||||
},
|
||||
"templates": [
|
||||
{
|
||||
"name": "EaglercraftX 1.8",
|
||||
"conf": "conf_template_eaglercraftX_1_8.json",
|
||||
"opts": "opts_template_eaglercraftX_1_8.txt",
|
||||
"allow": ["EAGLER_STANDARD_OFFLINE"],
|
||||
"parseTypes": ["EAGLERCRAFTX_1_8_OFFLINE"]
|
||||
},
|
||||
{
|
||||
"name": "EaglercraftX 1.8 Signed",
|
||||
"conf": "conf_template_eaglercraftX_1_8_signed.json",
|
||||
"opts": "opts_template_eaglercraftX_1_8.txt",
|
||||
"allow": ["EAGLER_SIGNED_OFFLINE"],
|
||||
"parseTypes": ["EAGLERCRAFTX_1_8_SIGNED"]
|
||||
},
|
||||
{
|
||||
"name": "Eaglercraft 1.5.2 (post-22w34a)",
|
||||
"conf": "conf_template_eaglercraft_1_5.json",
|
||||
"opts": "opts_template_eaglercraft_1_5.txt",
|
||||
"allow": ["EAGLER_STANDARD_1_5_OFFLINE"],
|
||||
"parseTypes": ["EAGLERCRAFT_1_5_NEW_OFFLINE"]
|
||||
},
|
||||
{
|
||||
"name": "Eaglercraft 1.5.2 Live Music (post-22w34a)",
|
||||
"conf": "conf_template_eaglercraft_1_5.json",
|
||||
"opts": "opts_template_eaglercraft_1_5_livestream.txt",
|
||||
"allow": ["EAGLER_STANDARD_1_5_OFFLINE"],
|
||||
"parseTypes": ["EAGLERCRAFT_1_5_NEW_OFFLINE"]
|
||||
},
|
||||
{
|
||||
"name": "Eaglercraft 1.5.2 (pre-22w34a)",
|
||||
"conf": "conf_template_eaglercraft_1_5_legacy.json",
|
||||
"opts": "opts_template_eaglercraft_1_5_legacy.txt",
|
||||
"allow": ["EAGLER_STANDARD_OFFLINE"],
|
||||
"parseTypes": ["EAGLERCRAFT_1_5_OLD_OFFLINE"]
|
||||
},
|
||||
{
|
||||
"name": "Eaglercraft Beta 1.3",
|
||||
"conf": "conf_template_eaglercraft_b1_3.json",
|
||||
"opts": null,
|
||||
"allow": ["EAGLER_STANDARD_OFFLINE"],
|
||||
"parseTypes": ["EAGLERCRAFT_BETA_B1_3_OFFLINE"]
|
||||
},
|
||||
{
|
||||
"name": "PeytonPlayz585 Beta 1.7.3",
|
||||
"conf": "conf_template_peytonplayz585_b1_7_3.json",
|
||||
"opts": "opts_template_peytonplayz585_b1_7_3.txt",
|
||||
"allow": ["EAGLER_STANDARD_OFFLINE"],
|
||||
"parseTypes": ["PEYTONPLAYZ585_ALPHA_BETA"]
|
||||
},
|
||||
{
|
||||
"name": "PeytonPlayz585 Alpha 1.2.6",
|
||||
"conf": "conf_template_peytonplayz585_a1_2_6.json",
|
||||
"opts": "opts_template_peytonplayz585_a1_2_6.txt",
|
||||
"allow": ["EAGLER_STANDARD_OFFLINE"],
|
||||
"parseTypes": ["PEYTONPLAYZ585_ALPHA_BETA"]
|
||||
},
|
||||
{
|
||||
"name": "PeytonPlayz585 Indev",
|
||||
"conf": "conf_template_peytonplayz585_indev.json",
|
||||
"opts": null,
|
||||
"allow": ["EAGLER_STANDARD_OFFLINE"],
|
||||
"parseTypes": ["PEYTONPLAYZ585_INDEV"]
|
||||
},
|
||||
{
|
||||
"name": "Standard Offline Download",
|
||||
"conf": "conf_template_standard_offline.json",
|
||||
"opts": null,
|
||||
"allow": ["EAGLER_STANDARD_OFFLINE"],
|
||||
"parseTypes": ["EXPORTED_STANDARD_OFFLINE"]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -75,4 +75,4 @@ function countdown() {
|
||||
<p id="countdown" style="text-align:center;">(Game will launch in 5)</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
@ -56,4 +56,4 @@ function countdown() {
|
||||
<p id="countdown" style="text-align:center;">(Game will launch in 5)</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
@ -56,4 +56,4 @@ function countdown() {
|
||||
<p id="countdown" style="text-align:center;">(Game will launch in 5)</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
@ -37,4 +37,4 @@ ${classes_js}
|
||||
</head>
|
||||
<body style="margin:0px;width:100%;height:100%;overflow:hidden;" id="game_frame">
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
@ -35,4 +35,4 @@ ${classes_js}
|
||||
</head>
|
||||
<body style="margin:0px;width:100%;height:100%;overflow:hidden;" id="game_frame">
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
@ -31,7 +31,8 @@
|
||||
"forceWebViewSupport": false,
|
||||
"enableServerCookies": true,
|
||||
"enableDownloadOfflineButton": true,
|
||||
"resourcePacksDB": "resourcePacks",
|
||||
"downloadOfflineButtonLink": null,
|
||||
"resourcePacksDB": "resourcePacks_starlike",
|
||||
"enableWebViewCSP": true,
|
||||
"checkRelaysForUpdates": true,
|
||||
"allowServerRedirects": true,
|
||||
@ -39,15 +40,16 @@
|
||||
"html5CursorSupport": false,
|
||||
"allowFNAWSkins": true,
|
||||
"allowVoiceClient": true,
|
||||
"worldsDB": "worlds",
|
||||
"worldsDB": "worlds_starlike",
|
||||
"demoMode": false,
|
||||
"localStorageNamespace": "_eaglercraftX",
|
||||
"localStorageNamespace": "_eaglercraftX_starlike",
|
||||
"enableSignatureBadge": false,
|
||||
"lang": "en_US",
|
||||
"enableMinceraft": true,
|
||||
"autoFixLegacyStyleAttr": true,
|
||||
"allowUpdateDL": true,
|
||||
"logInvalidCerts": false,
|
||||
"logInvalidCerts": true,
|
||||
"checkGLErrors": false,
|
||||
"checkShaderGLErrors": false,
|
||||
"crashOnUncaughtExceptions": false,
|
||||
"forceWebGL1": false,
|
||||
@ -62,5 +64,6 @@
|
||||
"disableBlobURLs": false,
|
||||
"eaglerNoDelay": false,
|
||||
"ramdiskMode": false,
|
||||
"singleThreadMode": false
|
||||
}
|
||||
"singleThreadMode": false,
|
||||
"enableEPKVersionCheck": true
|
||||
}
|
||||
|
@ -1,66 +0,0 @@
|
||||
{
|
||||
"joinServer": null,
|
||||
"servers": [
|
||||
{
|
||||
"addr": "ws://localhost:8081/",
|
||||
"hideAddr": false,
|
||||
"name": "Local test server"
|
||||
}
|
||||
],
|
||||
"relays": [
|
||||
{
|
||||
"addr": "wss://relay.deev.is/",
|
||||
"primary": "$random_relay_primary_0",
|
||||
"comment": "lax1dude relay #1"
|
||||
},
|
||||
{
|
||||
"addr": "wss://relay.lax1dude.net/",
|
||||
"primary": "$random_relay_primary_1",
|
||||
"comment": "lax1dude relay #2"
|
||||
},
|
||||
{
|
||||
"addr": "wss://relay.shhnowisnottheti.me/",
|
||||
"primary": "$random_relay_primary_2",
|
||||
"comment": "ayunami relay #1"
|
||||
}
|
||||
],
|
||||
"openDebugConsoleOnLaunch": false,
|
||||
"showBootMenuOnLaunch": false,
|
||||
"bootMenuBlocksUnsignedClients": false,
|
||||
"allowBootMenu": true,
|
||||
"forceWebViewSupport": false,
|
||||
"enableServerCookies": true,
|
||||
"enableDownloadOfflineButton": true,
|
||||
"resourcePacksDB": "resourcePacks",
|
||||
"enableWebViewCSP": true,
|
||||
"checkRelaysForUpdates": true,
|
||||
"allowServerRedirects": true,
|
||||
"allowUpdateSvc": true,
|
||||
"html5CursorSupport": false,
|
||||
"allowFNAWSkins": true,
|
||||
"allowVoiceClient": true,
|
||||
"worldsDB": "worlds",
|
||||
"demoMode": true,
|
||||
"localStorageNamespace": "_eaglercraftX",
|
||||
"enableSignatureBadge": false,
|
||||
"lang": "en_US",
|
||||
"enableMinceraft": true,
|
||||
"autoFixLegacyStyleAttr": true,
|
||||
"allowUpdateDL": true,
|
||||
"logInvalidCerts": false,
|
||||
"checkShaderGLErrors": false,
|
||||
"crashOnUncaughtExceptions": false,
|
||||
"forceWebGL1": false,
|
||||
"forceWebGL2": false,
|
||||
"allowExperimentalWebGL1": true,
|
||||
"useWebGLExt": true,
|
||||
"useDelayOnSwap": false,
|
||||
"useJOrbisAudioDecoder": false,
|
||||
"useXHRFetch": false,
|
||||
"useVisualViewport": true,
|
||||
"deobfStackTraces": true,
|
||||
"disableBlobURLs": false,
|
||||
"eaglerNoDelay": false,
|
||||
"ramdiskMode": false,
|
||||
"singleThreadMode": false
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
{
|
||||
"joinServer": null,
|
||||
"servers": [
|
||||
{
|
||||
"addr": "ws://localhost:8081/",
|
||||
"hideAddr": false,
|
||||
"name": "Local test server"
|
||||
}
|
||||
],
|
||||
"relays": [
|
||||
{
|
||||
"addr": "wss://relay.deev.is/",
|
||||
"primary": "$random_relay_primary_0",
|
||||
"comment": "lax1dude relay #1"
|
||||
},
|
||||
{
|
||||
"addr": "wss://relay.lax1dude.net/",
|
||||
"primary": "$random_relay_primary_1",
|
||||
"comment": "lax1dude relay #2"
|
||||
},
|
||||
{
|
||||
"addr": "wss://relay.shhnowisnottheti.me/",
|
||||
"primary": "$random_relay_primary_2",
|
||||
"comment": "ayunami relay #1"
|
||||
}
|
||||
],
|
||||
"openDebugConsoleOnLaunch": false,
|
||||
"showBootMenuOnLaunch": false,
|
||||
"bootMenuBlocksUnsignedClients": false,
|
||||
"allowBootMenu": true,
|
||||
"forceWebViewSupport": false,
|
||||
"enableServerCookies": true,
|
||||
"enableDownloadOfflineButton": true,
|
||||
"resourcePacksDB": "resourcePacks",
|
||||
"enableWebViewCSP": true,
|
||||
"checkRelaysForUpdates": true,
|
||||
"allowServerRedirects": true,
|
||||
"allowUpdateSvc": true,
|
||||
"html5CursorSupport": true,
|
||||
"allowFNAWSkins": true,
|
||||
"allowVoiceClient": true,
|
||||
"worldsDB": "worlds",
|
||||
"demoMode": false,
|
||||
"localStorageNamespace": "_eaglercraftX",
|
||||
"enableSignatureBadge": false,
|
||||
"lang": "en_US",
|
||||
"enableMinceraft": true,
|
||||
"autoFixLegacyStyleAttr": true,
|
||||
"allowUpdateDL": true,
|
||||
"logInvalidCerts": false,
|
||||
"checkShaderGLErrors": false,
|
||||
"crashOnUncaughtExceptions": false,
|
||||
"forceWebGL1": false,
|
||||
"forceWebGL2": false,
|
||||
"allowExperimentalWebGL1": true,
|
||||
"useWebGLExt": true,
|
||||
"useDelayOnSwap": false,
|
||||
"useJOrbisAudioDecoder": false,
|
||||
"useXHRFetch": false,
|
||||
"useVisualViewport": true,
|
||||
"deobfStackTraces": true,
|
||||
"disableBlobURLs": false,
|
||||
"eaglerNoDelay": false,
|
||||
"ramdiskMode": false,
|
||||
"singleThreadMode": false
|
||||
}
|
@ -49,4 +49,4 @@
|
||||
"hideDownServers": false,
|
||||
"serverListTitle": null,
|
||||
"serverListLink": null
|
||||
}
|
||||
}
|
||||
|
@ -29,4 +29,4 @@
|
||||
hide_down: false,
|
||||
serverListTitle: "",
|
||||
serverListLink: ""
|
||||
}[/NBT]
|
||||
}[/NBT]
|
||||
|
@ -60,4 +60,4 @@
|
||||
"hideDownServers": false,
|
||||
"serverListTitle": null,
|
||||
"serverListLink": null
|
||||
}
|
||||
}
|
||||
|
@ -3,4 +3,4 @@
|
||||
"playerUsername": null,
|
||||
"serverIP": null,
|
||||
"joinServerOnLaunch": null
|
||||
}
|
||||
}
|
||||
|
@ -3,4 +3,4 @@
|
||||
"playerUsername": null,
|
||||
"serverIP": null,
|
||||
"joinServerOnLaunch": null
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 917 B After Width: | Height: | Size: 627 B |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 4.5 KiB |
@ -162,7 +162,7 @@ void main() {
|
||||
|
||||
#ifdef COMPILE_ENABLE_MC_LIGHTING
|
||||
#ifdef COMPILE_NORMAL_ATTRIB
|
||||
vec3 normal = normalize(v_normal3f);
|
||||
vec3 normal = v_normal3f;
|
||||
#else
|
||||
vec3 normal = u_uniformNormal3f;
|
||||
#endif
|
||||
|
@ -83,6 +83,7 @@ uniform sampler2D u_metalsLUT;
|
||||
#define LIB_INCLUDE_PBR_LIGHTING_FUNCTION
|
||||
#define LIB_INCLUDE_PBR_LIGHTING_PREFETCH
|
||||
#EAGLER INCLUDE (3) "eagler:glsl/deferred/lib/pbr_lighting.glsl"
|
||||
#EAGLER INCLUDE (4) "eagler:glsl/deferred/lib/branchless_comparison.glsl"
|
||||
|
||||
uniform sampler2D u_irradianceMap;
|
||||
|
||||
@ -139,14 +140,14 @@ void main() {
|
||||
float skyLight = max(lightmapCoords2f.g * 2.0 - 1.0, 0.0);
|
||||
float shadowSample = 1.0;
|
||||
vec4 shadowWorldPos4f = worldPosition4f;
|
||||
shadowWorldPos4f.xyz += normalVector3f * 0.05;
|
||||
shadowWorldPos4f.xyz += normalVector3f * 0.1;
|
||||
|
||||
vec4 shadowTexPos4f;
|
||||
vec2 tmpVec2;
|
||||
for(;;) {
|
||||
shadowTexPos4f = u_sunShadowMatrixLOD04f * shadowWorldPos4f;
|
||||
if(shadowTexPos4f.xyz == clamp(shadowTexPos4f.xyz, vec3(0.005), vec3(0.995))) {
|
||||
shadowSample = textureLod(u_sunShadowDepthTexture, vec3(shadowTexPos4f.xy * vec2(1.0, SUN_SHADOW_MAP_FRAC), shadowTexPos4f.z), 0.0);
|
||||
shadowSample = textureLod(u_sunShadowDepthTexture, vec3(shadowTexPos4f.xy * vec2(1.0, SUN_SHADOW_MAP_FRAC), shadowTexPos4f.z + 0.0001), 0.0);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -175,7 +176,7 @@ void main() {
|
||||
#ifdef DO_COMPILE_SUN_SHADOWS
|
||||
lightColor3f *= shadowSample * skyLight;
|
||||
#endif
|
||||
vec3 normalWrap3f = normalVector3f * (dot(-worldDirection4f.xyz, normalVector3f) < 0.0 ? -1.0 : 1.0);
|
||||
vec3 normalWrap3f = normalVector3f * COMPARE_LT_C_C(dot(-worldDirection4f.xyz, normalVector3f), 0.0, -1.0, 1.0);
|
||||
lightColor3f = eaglercraftLighting(diffuseColor4f.rgb, lightColor3f, -worldDirection4f.xyz, u_sunDirection4f.xyz, normalWrap3f, materialData3f, metalN, metalK) * u_blockSkySunDynamicLightFac4f.z;
|
||||
}
|
||||
|
||||
@ -194,8 +195,8 @@ void main() {
|
||||
vec4 sample2 = textureLod(u_irradianceMap, irradianceMapSamplePos2f.xz * vec2(0.5, -0.25) + vec2(0.5, 0.75), 0.0);
|
||||
skyLight += mix(sample1.rgb, sample2.rgb, smoothstep(0.0, 1.0, irradianceMapSamplePos2f.y * -12.5 + 0.5)).rgb;
|
||||
}else {
|
||||
irradianceMapSamplePos2f.xz *= vec2(0.5, irradianceMapSamplePos2f.y > 0.0 ? 0.25 : -0.25);
|
||||
irradianceMapSamplePos2f.xz += vec2(0.5, irradianceMapSamplePos2f.y > 0.0 ? 0.25 : 0.75);
|
||||
irradianceMapSamplePos2f.xz *= vec2(0.5, COMPARE_GT_C_C(irradianceMapSamplePos2f.y, 0.0, 0.25, -0.25));
|
||||
irradianceMapSamplePos2f.xz += vec2(0.5, COMPARE_GT_C_C(irradianceMapSamplePos2f.y, 0.0, 0.25, 0.75));
|
||||
skyLight += textureLod(u_irradianceMap, irradianceMapSamplePos2f.xz, 0.0).rgb;
|
||||
}
|
||||
skyLight *= lightmapCoords2f.g * u_sunColor3f_sky1f.w;
|
||||
@ -206,18 +207,21 @@ void main() {
|
||||
|
||||
vec3 dlightDist3f, dlightDir3f, dlightColor3f;
|
||||
int safeLightCount = u_dynamicLightCount1i > 12 ? 0 : u_dynamicLightCount1i; // hate this
|
||||
float cm;
|
||||
for(int i = 0; i < safeLightCount; ++i) {
|
||||
dlightDist3f = worldPosition4f.xyz - u_dynamicLightArray[i].u_lightPosition4f.xyz;
|
||||
dlightDir3f = normalize(dlightDist3f);
|
||||
dlightDir3f = dlightDir3f * (dot(dlightDir3f, normalVector3f) < 0.0 ? 1.0 : -1.0);
|
||||
dlightDir3f = dlightDir3f * COMPARE_LT_C_C(dot(dlightDir3f, normalVector3f), 0.0, 1.0, -1.0);
|
||||
dlightDir3f = materialData3f.b == 1.0 ? normalVector3f : -dlightDir3f;
|
||||
if(dot(dlightDir3f, normalVector3f) <= 0.0) {
|
||||
continue;
|
||||
}
|
||||
dlightColor3f = u_dynamicLightArray[i].u_lightColor4f.rgb / dot(dlightDist3f, dlightDist3f);
|
||||
if(dlightColor3f.r + dlightColor3f.g + dlightColor3f.b < 0.025) {
|
||||
cm = dlightColor3f.r + dlightColor3f.g + dlightColor3f.b;
|
||||
if(cm < 0.025) {
|
||||
continue;
|
||||
}
|
||||
dlightColor3f *= ((cm - 0.025) / cm);
|
||||
lightColor3f += eaglercraftLighting(diffuseColor4f.rgb, dlightColor3f, -worldDirection4f.xyz, dlightDir3f, normalVector3f, materialData3f, metalN, metalK) * u_blockSkySunDynamicLightFac4f.w;
|
||||
}
|
||||
|
||||
|
@ -40,5 +40,6 @@ void main() {
|
||||
}
|
||||
gbufferColor4f = vec4(diffuseRGBA.rgb, v_lightmap2f.r);
|
||||
gbufferNormal4f = vec4(0.5, 0.5, 1.0, v_lightmap2f.g);
|
||||
gbufferMaterial4f = vec4(texture(u_samplerNormalMaterial, vec2(v_texCoord2f.x, v_texCoord2f.y * u_textureYScale2f.x + u_textureYScale2f.y)).rgb, 1.0);
|
||||
gbufferMaterial4f = texture(u_samplerNormalMaterial, vec2(v_texCoord2f.x, v_texCoord2f.y * u_textureYScale2f.x + u_textureYScale2f.y));
|
||||
gbufferMaterial4f.a = 0.502 - gbufferMaterial4f.a * 0.502;
|
||||
}
|
||||
|
@ -1 +1 @@
|
||||
these are just low quality fallback material textures for the default vanilla resource pack when no PBR resource pack is loaded, if you would like to make a PBR resource pack put your _n and _s textures in the "/assets/minecraft/textures/" directory of your zip file, do not modify any files within "/assets/eagler/glsl/deferred/assets_pbr/textures/" because they will not be recognized
|
||||
these are just low quality fallback material textures for the default vanilla resource pack when no PBR resource pack is loaded, if you would like to make a PBR resource pack put your _n and _s textures in the "/assets/minecraft/textures/" directory of your zip file, do not modify any files within "/assets/eagler/glsl/deferred/assets_pbr/textures/" because they will not be recognized
|
||||
|
@ -60,6 +60,7 @@ uniform float u_skyLightFactor1f;
|
||||
#endif
|
||||
|
||||
#EAGLER INCLUDE (3) "eagler:glsl/deferred/lib/pbr_env_map.glsl"
|
||||
#EAGLER INCLUDE (4) "eagler:glsl/deferred/lib/branchless_comparison.glsl"
|
||||
|
||||
void main() {
|
||||
vec3 diffuseColor3f;
|
||||
@ -68,7 +69,7 @@ void main() {
|
||||
vec4 materialData4f;
|
||||
|
||||
float depth = textureLod(u_gbufferDepthTexture, v_position2f, 0.0).r;
|
||||
if(depth < 0.00001) {
|
||||
if(depth == 0.0) {
|
||||
discard;
|
||||
}
|
||||
|
||||
@ -86,7 +87,7 @@ void main() {
|
||||
|
||||
#ifdef COMPILE_GLOBAL_AMBIENT_OCCLUSION
|
||||
vec4 ao = textureLod(u_ssaoTexture, min(v_position2f * u_halfResolutionPixelAlignment2f, 1.0), 0.0);
|
||||
ao.g = ao.b > 0.0 ? ao.g : 1.0;
|
||||
ao.g = mix(COMPARE_GT_0_1(0.0, ao.b), 1.0, ao.g);
|
||||
shadow = mix(shadow, shadow * ao.g, 0.9);
|
||||
#endif
|
||||
|
||||
@ -102,8 +103,8 @@ void main() {
|
||||
vec4 sample2 = textureLod(u_irradianceMap, irradianceMapSamplePos2f.xz * vec2(0.5, -0.25) + vec2(0.5, 0.75), 0.0);
|
||||
skyLight += mix(sample1.rgb, sample2.rgb, smoothstep(0.0, 1.0, irradianceMapSamplePos2f.y * -12.5 + 0.5)).rgb;
|
||||
}else {
|
||||
irradianceMapSamplePos2f.xz *= vec2(0.5, irradianceMapSamplePos2f.y > 0.0 ? 0.25 : -0.25);
|
||||
irradianceMapSamplePos2f.xz += vec2(0.5, irradianceMapSamplePos2f.y > 0.0 ? 0.25 : 0.75);
|
||||
irradianceMapSamplePos2f.xz *= vec2(0.5, COMPARE_GT_C_C(irradianceMapSamplePos2f.y, 0.0, 0.25, -0.25));
|
||||
irradianceMapSamplePos2f.xz += vec2(0.5, COMPARE_GT_C_C(irradianceMapSamplePos2f.y, 0.0, 0.25, 0.75));
|
||||
skyLight += textureLod(u_irradianceMap, irradianceMapSamplePos2f.xz, 0.0).rgb;
|
||||
}
|
||||
|
||||
@ -114,8 +115,8 @@ void main() {
|
||||
vec3 specular = vec3(0.0);
|
||||
|
||||
#ifdef COMPILE_ENV_MAP_REFLECTIONS
|
||||
float f = materialData4f.g < 0.06 ? 1.0 : 0.0;
|
||||
f += materialData4f.r < 0.5 ? 1.0 : 0.0;
|
||||
float f = COMPARE_LT_0_ANY(materialData4f.g, 0.06);
|
||||
f += COMPARE_LT_0_ANY(materialData4f.r, 0.5);
|
||||
while((materialData4f.a >= 0.5 ? f : -1.0) == 0.0) {
|
||||
vec4 worldPosition4f = vec4(v_position2f, depth, 1.0) * 2.0 - 1.0;
|
||||
worldPosition4f = u_inverseProjMatrix4f * worldPosition4f;
|
||||
@ -137,12 +138,13 @@ void main() {
|
||||
vec4 sample2 = textureLod(u_environmentMap, reflectDir.xz * vec2(0.5, -0.25) + vec2(0.5, 0.75), 0.0);
|
||||
envMapSample4f = vec4(mix(sample1.rgb, sample2.rgb, smoothstep(0.0, 1.0, reflectDir.y * -12.5 + 0.5)).rgb, min(sample1.a, sample2.a));
|
||||
}else {
|
||||
reflectDir.xz = reflectDir.xz * vec2(0.5, reflectDir.y > 0.0 ? 0.25 : -0.25);
|
||||
reflectDir.xz += vec2(0.5, reflectDir.y > 0.0 ? 0.25 : 0.75);
|
||||
reflectDir.xz = reflectDir.xz * vec2(0.5, COMPARE_GT_C_C(reflectDir.y, 0.0, 0.25, -0.25));
|
||||
reflectDir.xz += vec2(0.5, COMPARE_GT_C_C(reflectDir.y, 0.0, 0.25, 0.75));
|
||||
envMapSample4f = textureLod(u_environmentMap, reflectDir.xz, 0.0);
|
||||
}
|
||||
if(envMapSample4f.a > 0.0) {
|
||||
specular = eaglercraftIBL_Specular(diffuseColor3f.rgb, envMapSample4f.rgb, viewDir3f, normalVector3f, materialData4f.rgb);
|
||||
envMapSample4f.a += min(lightmapCoords2f.g * 2.0, 1.0) * (1.0 - envMapSample4f.a);
|
||||
if(envMapSample4f.a == 1.0) {
|
||||
specular = eaglercraftIBL_Specular(diffuseColor3f.rgb, envMapSample4f.rgb * envMapSample4f.a, viewDir3f, normalVector3f, materialData4f.rgb);
|
||||
specular *= 1.0 - sqrt(posDst) * 0.2;
|
||||
}
|
||||
break;
|
||||
@ -151,8 +153,8 @@ void main() {
|
||||
|
||||
#ifdef COMPILE_SCREEN_SPACE_REFLECTIONS
|
||||
#ifndef COMPILE_ENV_MAP_REFLECTIONS
|
||||
float f = materialData4f.g < 0.06 ? 1.0 : 0.0;
|
||||
f += materialData4f.r < 0.5 ? 1.0 : 0.0;
|
||||
float f = COMPARE_LT_0_ANY(materialData4f.g, 0.06);
|
||||
f += COMPARE_LT_0_ANY(materialData4f.r, 0.5);
|
||||
if(f == 0.0) {
|
||||
#else
|
||||
if((materialData4f.a < 0.5 ? f : -1.0) == 0.0) {
|
||||
|
@ -73,8 +73,12 @@ in vec3 v_viewdir3f;
|
||||
uniform vec2 u_textureCoords01;
|
||||
#endif
|
||||
#else
|
||||
#ifdef COMPILE_SUBSURFACE_SCATTERING
|
||||
uniform vec4 u_materialConstants4f;
|
||||
#else
|
||||
uniform vec3 u_materialConstants3f;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef COMPILE_NORMAL_MATERIAL_TEXTURE
|
||||
mat3 cotangent_frame(in vec3 N, in vec3 p, in vec2 uv) {
|
||||
@ -104,7 +108,7 @@ void main() {
|
||||
|
||||
vec3 normal;
|
||||
#ifdef COMPILE_NORMAL_ATTRIB
|
||||
normal = normalize(v_normal3f);
|
||||
normal = v_normal3f;
|
||||
#else
|
||||
normal = u_uniformNormal3f;
|
||||
#endif
|
||||
@ -155,14 +159,21 @@ void main() {
|
||||
normal = cf * vec3(normal2, sqrt(1.0 - dot(normal2, normal2)));
|
||||
}
|
||||
uv2.y += 0.5;
|
||||
vec3 material = texture(u_samplerNormalMaterial, uv2).rgb;
|
||||
vec4 material = texture(u_samplerNormalMaterial, uv2);
|
||||
#else
|
||||
vec3 material = u_materialConstants3f;
|
||||
#ifdef COMPILE_SUBSURFACE_SCATTERING
|
||||
vec4 material = u_materialConstants4f;
|
||||
#else
|
||||
vec4 material = vec4(u_materialConstants3f, 1.0);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
material.a = 1.0 - material.a + u_useEnvMap1f;
|
||||
material.a *= 0.502;
|
||||
|
||||
gbufferColor4f.rgb = color.rgb;
|
||||
gbufferColor4f.a = lightmap.r;
|
||||
gbufferNormal4f.rgb = normal * 0.5 + 0.5;
|
||||
gbufferNormal4f.a = lightmap.g;
|
||||
gbufferMaterial4f = vec4(material.rgb, u_useEnvMap1f);
|
||||
gbufferMaterial4f = material;
|
||||
}
|
||||
|
@ -24,7 +24,6 @@ layout(location = 0) out vec4 output4f;
|
||||
|
||||
in vec2 v_position2f;
|
||||
|
||||
uniform sampler2D u_gbufferDepthTexture;
|
||||
uniform sampler2D u_gbufferNormalTexture;
|
||||
uniform sampler2D u_fogDepthTexture;
|
||||
|
||||
@ -34,6 +33,7 @@ uniform sampler2D u_lightShaftsTexture;
|
||||
|
||||
#ifdef COMPILE_FOG_ATMOSPHERE
|
||||
uniform sampler2D u_environmentMap;
|
||||
uniform sampler2D u_skyTexture;
|
||||
uniform vec3 u_sunColorAdd3f;
|
||||
#endif
|
||||
|
||||
@ -52,16 +52,11 @@ void main() {
|
||||
vec4 fragPos4f = vec4(v_position2f, textureLod(u_fogDepthTexture, v_position2f, 0.0).r, 1.0);
|
||||
|
||||
#ifdef COMPILE_FOG_ATMOSPHERE
|
||||
if(fragPos4f.z <= 0.0000001) {
|
||||
if(fragPos4f.z == 0.0) {
|
||||
discard;
|
||||
}
|
||||
#endif
|
||||
|
||||
float solidDepth = textureLod(u_gbufferDepthTexture, v_position2f, 0.0).r;
|
||||
if(solidDepth != fragPos4f.z) {
|
||||
discard;
|
||||
}
|
||||
|
||||
fragPos4f.xyz *= 2.0;
|
||||
fragPos4f.xyz -= 1.0;
|
||||
|
||||
@ -85,18 +80,26 @@ void main() {
|
||||
fragPos4f.xz *= 0.75;
|
||||
|
||||
vec3 envMapSample3f;
|
||||
vec3 skyboxSample3f;
|
||||
|
||||
fragPos4f.xz *= vec2(-0.5, -0.25);
|
||||
fragPos4f.xz += vec2(0.5, 0.25);
|
||||
envMapSample3f = textureLod(u_environmentMap, fragPos4f.xz, 0.0).rgb + u_sunColorAdd3f;
|
||||
|
||||
skyboxSample3f = textureLod(u_skyTexture, v_position2f, 0.0).rgb;
|
||||
|
||||
#ifdef COMPILE_FOG_LIGHT_SHAFTS
|
||||
f2 = textureLod(u_lightShaftsTexture, v_position2f, 0.0).r;
|
||||
envMapSample3f *= pow(f2, 2.25);
|
||||
f = (f * 0.85 + 0.2) * f2 + f * (1.0 - f2);
|
||||
f2 = textureLod(u_lightShaftsTexture, v_position2f, 0.0).r * 0.95 + 0.05;
|
||||
envMapSample3f *= (f2 * 0.8 + 0.2);
|
||||
skyboxSample3f *= f2 * f2 * f2;
|
||||
f = min(f + 0.15, 1.0);
|
||||
f2 = 0.5 + f * 0.5;
|
||||
#else
|
||||
f = max(f * 1.0375 - 0.0375, 0.0);
|
||||
f2 = 0.3 + f * 0.7;
|
||||
#endif
|
||||
|
||||
output4f = vec4(envMapSample3f * fogColor4f.rgb, f);
|
||||
output4f = vec4(mix(envMapSample3f, skyboxSample3f, f2) * fogColor4f.rgb, f);
|
||||
#else
|
||||
output4f = vec4(fogColor4f.rgb, f);
|
||||
#endif
|
||||
|
@ -7,4 +7,4 @@ minecraft:redstone_torch,0,1.0000,0.1578,0.0000,4.0
|
||||
minecraft:sea_lantern,0,0.5530,0.6468,1.0000,10.0,
|
||||
minecraft:lava_bucket,0,1.0000,0.4461,0.1054,6.0,
|
||||
minecraft:nether_star,0,0.5711,0.6611,1.0000,6.0
|
||||
minecraft:ender_eye,0,0.1990,0.7750,0.4130,4.0
|
||||
minecraft:ender_eye,0,0.1990,0.7750,0.4130,4.0
|
||||
|
|
@ -21,7 +21,7 @@ precision highp sampler2DShadow;
|
||||
in vec4 v_position4f;
|
||||
|
||||
#ifdef COMPILE_FOG_LIGHT_SHAFTS
|
||||
in vec2 v_positionClip2f;
|
||||
in vec3 v_positionClip3f;
|
||||
#endif
|
||||
|
||||
#ifdef COMPILE_TEXTURE_ATTRIB
|
||||
@ -129,8 +129,12 @@ layout(std140) uniform u_worldLightingData {
|
||||
#ifdef COMPILE_NORMAL_MATERIAL_TEXTURE
|
||||
uniform sampler2D u_samplerNormalMaterial;
|
||||
#else
|
||||
#ifdef COMPILE_SUBSURFACE_SCATTERING
|
||||
uniform vec4 u_materialConstants4f;
|
||||
#else
|
||||
uniform vec3 u_materialConstants3f;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
uniform sampler2D u_metalsLUT;
|
||||
|
||||
@ -158,6 +162,7 @@ uniform sampler2D u_lightShaftsTexture;
|
||||
#endif
|
||||
|
||||
#EAGLER INCLUDE (4) "eagler:glsl/deferred/lib/pbr_env_map.glsl"
|
||||
#EAGLER INCLUDE (4) "eagler:glsl/deferred/lib/branchless_comparison.glsl"
|
||||
|
||||
#ifdef DO_COMPILE_SUN_SHADOWS
|
||||
uniform sampler2DShadow u_sunShadowDepthTexture;
|
||||
@ -167,14 +172,14 @@ vec2(-0.077, 0.995), vec2(0.998, 0.015),
|
||||
vec2(-0.116, -0.987), vec2(-0.916, 0.359),
|
||||
vec2(-0.697, -0.511), vec2(0.740, -0.612),
|
||||
vec2(0.675, 0.682));
|
||||
#define SMOOTH_SHADOW_SAMPLES 1.0 / 8.0
|
||||
#define SMOOTH_SHADOW_RADIUS 0.00075
|
||||
#define SMOOTH_SHADOW_SAMPLES (1.0 / 8.0)
|
||||
#define SMOOTH_SHADOW_RADIUS 0.000488
|
||||
#define SMOOTH_SHADOW_POISSON_SAMPLE(idx, tex, lod, vec3Pos, accum, tmpVec2)\
|
||||
tmpVec2 = vec3Pos.xy + POISSON_DISK[idx] * SMOOTH_SHADOW_RADIUS;\
|
||||
tmpVec2 = clamp(tmpVec2, vec2(0.001), vec2(0.999));\
|
||||
tmpVec2.y += lod;\
|
||||
tmpVec2.y *= SUN_SHADOW_MAP_FRAC;\
|
||||
accum += textureLod(tex, vec3(tmpVec2, vec3Pos.z), 0.0) * SMOOTH_SHADOW_SAMPLES;
|
||||
accum += textureLod(tex, vec3(tmpVec2, vec3Pos.z + 0.0001), 0.0);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -184,7 +189,7 @@ void main() {
|
||||
vec4 diffuseColor4f;
|
||||
vec3 normalVector3f;
|
||||
vec2 lightmapCoords2f;
|
||||
vec3 materialData3f;
|
||||
vec4 materialData4f;
|
||||
float block1f;
|
||||
|
||||
// =========== RESOLVE CONSTANTS ============ //
|
||||
@ -206,8 +211,8 @@ void main() {
|
||||
#endif
|
||||
|
||||
#ifdef COMPILE_NORMAL_ATTRIB
|
||||
normalVector3f = normalize(v_normal3f);
|
||||
block1f = v_block1f;
|
||||
normalVector3f = v_normal3f;
|
||||
block1f = round(v_block1f);
|
||||
#else
|
||||
normalVector3f = u_uniformNormal3f;
|
||||
block1f = u_blockConstant1f;
|
||||
@ -270,13 +275,17 @@ void main() {
|
||||
#ifdef COMPILE_NORMAL_MATERIAL_TEXTURE
|
||||
vec2 uv2 = vec2(1.0, 0.5) * texCoords2f;
|
||||
uv2.y += 0.5;
|
||||
materialData3f = texture(u_samplerNormalMaterial, uv2).rgb;
|
||||
materialData4f = texture(u_samplerNormalMaterial, uv2);
|
||||
#else
|
||||
materialData3f = u_materialConstants3f;
|
||||
#ifdef COMPILE_SUBSURFACE_SCATTERING
|
||||
materialData4f = u_materialConstants4f;
|
||||
#else
|
||||
materialData4f = vec4(u_materialConstants3f, 1.0);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
vec3 metalN, metalK;
|
||||
PREFETCH_METALS(diffuseColor4f.rgb, materialData3f.g, metalN, metalK)
|
||||
PREFETCH_METALS(diffuseColor4f.rgb, materialData4f.g, metalN, metalK)
|
||||
|
||||
// ============ SUN LIGHTING ============== //
|
||||
|
||||
@ -292,7 +301,7 @@ void main() {
|
||||
float skyLight = max(lightmapCoords2f.g * 2.0 - 1.0, 0.0);
|
||||
float shadowSample = 1.0;
|
||||
vec4 shadowWorldPos4f = worldPosition4f;
|
||||
shadowWorldPos4f.xyz += normalVector3f * 0.05;
|
||||
shadowWorldPos4f.xyz += normalVector3f * 0.1;
|
||||
|
||||
vec4 shadowTexPos4f;
|
||||
vec2 tmpVec2;
|
||||
@ -301,7 +310,6 @@ void main() {
|
||||
if(shadowTexPos4f.xyz == clamp(shadowTexPos4f.xyz, vec3(0.005), vec3(0.995))) {
|
||||
shadowSample = textureLod(u_sunShadowDepthTexture, vec3(shadowTexPos4f.xy * vec2(1.0, SUN_SHADOW_MAP_FRAC), shadowTexPos4f.z), 0.0);
|
||||
#ifdef COMPILE_SUN_SHADOW_SMOOTH
|
||||
shadowSample *= SMOOTH_SHADOW_SAMPLES;
|
||||
SMOOTH_SHADOW_POISSON_SAMPLE(0, u_sunShadowDepthTexture, 0.0, shadowTexPos4f.xyz, shadowSample, tmpVec2)
|
||||
SMOOTH_SHADOW_POISSON_SAMPLE(1, u_sunShadowDepthTexture, 0.0, shadowTexPos4f.xyz, shadowSample, tmpVec2)
|
||||
SMOOTH_SHADOW_POISSON_SAMPLE(2, u_sunShadowDepthTexture, 0.0, shadowTexPos4f.xyz, shadowSample, tmpVec2)
|
||||
@ -309,7 +317,7 @@ void main() {
|
||||
SMOOTH_SHADOW_POISSON_SAMPLE(4, u_sunShadowDepthTexture, 0.0, shadowTexPos4f.xyz, shadowSample, tmpVec2)
|
||||
SMOOTH_SHADOW_POISSON_SAMPLE(5, u_sunShadowDepthTexture, 0.0, shadowTexPos4f.xyz, shadowSample, tmpVec2)
|
||||
SMOOTH_SHADOW_POISSON_SAMPLE(6, u_sunShadowDepthTexture, 0.0, shadowTexPos4f.xyz, shadowSample, tmpVec2)
|
||||
shadowSample = max(shadowSample * 2.0 - 1.0, 0.0);
|
||||
shadowSample *= SMOOTH_SHADOW_SAMPLES;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
@ -339,19 +347,19 @@ void main() {
|
||||
#ifdef DO_COMPILE_SUN_SHADOWS
|
||||
lightColor3f *= shadowSample * skyLight;
|
||||
#endif
|
||||
lightColor3f = eaglercraftLighting(diffuseColor4f.rgb, lightColor3f, -worldDirection4f.xyz, u_sunDirection4f.xyz, normalVector3f, materialData3f, metalN, metalK) * u_blockSkySunDynamicLightFac4f.z;
|
||||
lightColor3f = eaglercraftLighting(diffuseColor4f.rgb, lightColor3f, -worldDirection4f.xyz, u_sunDirection4f.xyz, normalVector3f, materialData4f.rgb, metalN, metalK) * u_blockSkySunDynamicLightFac4f.z;
|
||||
}
|
||||
|
||||
float f;
|
||||
#ifdef COMPILE_PARABOLOID_ENV_MAP
|
||||
#if defined(COMPILE_PARABOLOID_ENV_MAP) && !defined(COMPILE_ENABLE_TEX_GEN)
|
||||
|
||||
// =========== ENVIRONMENT MAP =========== //
|
||||
|
||||
f = materialData3f.g < 0.06 ? 1.0 : 0.0;
|
||||
f += materialData3f.r < 0.5 ? 1.0 : 0.0;
|
||||
f = COMPARE_LT_0_ANY(materialData4f.g, 0.06);
|
||||
f += COMPARE_LT_0_ANY(materialData4f.r, 0.5);
|
||||
while(f == 0.0) {
|
||||
float dst2 = dot(worldPosition4f.xyz, worldPosition4f.xyz);
|
||||
if(dst2 > 16.0) {
|
||||
if(dst2 > 25.0) {
|
||||
break;
|
||||
}
|
||||
vec3 reflectDir = reflect(worldDirection4f.xyz, normalVector3f);
|
||||
@ -365,12 +373,13 @@ void main() {
|
||||
vec4 sample2 = textureLod(u_environmentMap, reflectDir.xz * vec2(0.5, -0.25) + vec2(0.5, 0.75), 0.0);
|
||||
envMapSample4f = vec4(mix(sample1.rgb, sample2.rgb, smoothstep(0.0, 1.0, reflectDir.y * -12.5 + 0.5)).rgb, min(sample1.a, sample2.a));
|
||||
}else {
|
||||
reflectDir.xz = reflectDir.xz * vec2(0.5, reflectDir.y > 0.0 ? 0.25 : -0.25);
|
||||
reflectDir.xz += vec2(0.5, reflectDir.y > 0.0 ? 0.25 : 0.75);
|
||||
reflectDir.xz = reflectDir.xz * vec2(0.5, COMPARE_GT_C_C(reflectDir.y, 0.0, 0.25, -0.25));
|
||||
reflectDir.xz += vec2(0.5, COMPARE_GT_C_C(reflectDir.y, 0.0, 0.25, 0.75));
|
||||
envMapSample4f = textureLod(u_environmentMap, reflectDir.xz, 0.0);
|
||||
}
|
||||
if(envMapSample4f.a > 0.0) {
|
||||
lightColor3f += eaglercraftIBL_Specular(diffuseColor4f.rgb, envMapSample4f.rgb, worldDirection4f.xyz, normalVector3f, materialData3f, metalN, metalK) * (1.0 - sqrt(dst2) * 0.25);
|
||||
envMapSample4f.a += min(lightmapCoords2f.g * 2.0, 1.0) * (1.0 - envMapSample4f.a);
|
||||
if(envMapSample4f.a == 1.0) {
|
||||
lightColor3f += eaglercraftIBL_Specular(diffuseColor4f.rgb, envMapSample4f.rgb * envMapSample4f.a, worldDirection4f.xyz, normalVector3f, materialData4f.rgb, metalN, metalK) * (1.0 - sqrt(dst2) * 0.2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -392,8 +401,8 @@ void main() {
|
||||
vec4 sample2 = textureLod(u_irradianceMap, irradianceMapSamplePos2f.xz * vec2(0.5, -0.25) + vec2(0.5, 0.75), 0.0);
|
||||
skyLight += mix(sample1.rgb, sample2.rgb, smoothstep(0.0, 1.0, irradianceMapSamplePos2f.y * -12.5 + 0.5)).rgb;
|
||||
}else {
|
||||
irradianceMapSamplePos2f.xz *= vec2(0.5, irradianceMapSamplePos2f.y > 0.0 ? 0.25 : -0.25);
|
||||
irradianceMapSamplePos2f.xz += vec2(0.5, irradianceMapSamplePos2f.y > 0.0 ? 0.25 : 0.75);
|
||||
irradianceMapSamplePos2f.xz *= vec2(0.5, COMPARE_GT_C_C(irradianceMapSamplePos2f.y, 0.0, 0.25, -0.25));
|
||||
irradianceMapSamplePos2f.xz += vec2(0.5, COMPARE_GT_C_C(irradianceMapSamplePos2f.y, 0.0, 0.25, 0.75));
|
||||
skyLight += textureLod(u_irradianceMap, irradianceMapSamplePos2f.xz, 0.0).rgb;
|
||||
}
|
||||
skyLight *= lightmapCoords2f.g * u_sunColor3f_sky1f.w;
|
||||
@ -404,18 +413,21 @@ void main() {
|
||||
|
||||
vec3 dlightDist3f, dlightDir3f, dlightColor3f;
|
||||
int safeLightCount = u_dynamicLightCount1i > 12 ? 0 : u_dynamicLightCount1i; // hate this
|
||||
float cm;
|
||||
for(int i = 0; i < safeLightCount; ++i) {
|
||||
dlightDist3f = worldPosition4f.xyz - u_dynamicLightArray[i].u_lightPosition4f.xyz;
|
||||
dlightDir3f = normalize(dlightDist3f);
|
||||
dlightDir3f = materialData3f.b == 1.0 ? normalVector3f : -dlightDir3f;
|
||||
dlightDir3f = materialData4f.b == 1.0 ? normalVector3f : -dlightDir3f;
|
||||
if(dot(dlightDir3f, normalVector3f) <= 0.0) {
|
||||
continue;
|
||||
}
|
||||
dlightColor3f = u_dynamicLightArray[i].u_lightColor4f.rgb / dot(dlightDist3f, dlightDist3f);
|
||||
if(dlightColor3f.r + dlightColor3f.g + dlightColor3f.b < 0.025) {
|
||||
cm = dlightColor3f.r + dlightColor3f.g + dlightColor3f.b;
|
||||
if(cm < 0.025) {
|
||||
continue;
|
||||
}
|
||||
lightColor3f += eaglercraftLighting(diffuseColor4f.rgb, dlightColor3f, -worldDirection4f.xyz, dlightDir3f, normalVector3f, materialData3f, metalN, metalK) * u_blockSkySunDynamicLightFac4f.w;
|
||||
dlightColor3f *= ((cm - 0.025) / cm);
|
||||
lightColor3f += eaglercraftLighting(diffuseColor4f.rgb, dlightColor3f, -worldDirection4f.xyz, dlightDir3f, normalVector3f, materialData4f.rgb, metalN, metalK) * u_blockSkySunDynamicLightFac4f.w;
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -425,7 +437,7 @@ void main() {
|
||||
vec4 fogBlend4f = vec4(0.0);
|
||||
#ifndef COMPILE_ENABLE_TEX_GEN
|
||||
while(u_fogParameters4f.x > 0.0) {
|
||||
float atmos = u_fogParameters4f.x >= 4.0 ? 4.0 : 0.0;
|
||||
float atmos = COMPARE_LT_C_C(u_fogParameters4f.x, 4.0, 0.0, 4.0);
|
||||
float type = u_fogParameters4f.x - atmos;
|
||||
fogBlend4f = mix(u_fogColorLight4f, u_fogColorDark4f, lightmapCoords2f.g);
|
||||
|
||||
@ -450,8 +462,10 @@ void main() {
|
||||
fogBlend4f.rgb *= textureLod(u_irradianceMap, atmosSamplePos.xz, 0.0).rgb;
|
||||
|
||||
#ifdef COMPILE_FOG_LIGHT_SHAFTS
|
||||
fogBlend4f.rgb *= pow(textureLod(u_lightShaftsTexture, v_positionClip2f * 0.5 + 0.5, 0.0).r * 0.9 + 0.1, 2.25);
|
||||
fogBlend4f.a = fogBlend4f.a * 0.9 + 0.1;
|
||||
fogBlend4f.rgb *= textureLod(u_lightShaftsTexture, (v_positionClip3f.xy / v_positionClip3f.z) * 0.5 + 0.5, 0.0).r * 0.76 + 0.24;
|
||||
fogBlend4f.a = min(fogBlend4f.a * 0.8 + 0.35, 1.0);
|
||||
#else
|
||||
fogBlend4f.a = max(fogBlend4f.a * 0.83 + 0.17, 0.0);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
@ -461,7 +475,7 @@ void main() {
|
||||
|
||||
vec3 blockLight = lightmapCoords2f.r * vec3(1.0, 0.5809, 0.2433) * 2.0 * u_blockSkySunDynamicLightFac4f.x;
|
||||
skyLight *= u_blockSkySunDynamicLightFac4f.y;
|
||||
float emissive = materialData3f.b == 1.0 ? 0.0 : materialData3f.b;
|
||||
float emissive = materialData4f.b == 1.0 ? 0.0 : materialData4f.b;
|
||||
diffuseColor4f.rgb *= max(skyLight + blockLight, vec3(emissive * emissive * 20.0 + 0.075)) * 0.075;
|
||||
diffuseColor4f.rgb += lightColor3f;
|
||||
|
||||
|
@ -21,7 +21,7 @@ in vec3 a_position3f;
|
||||
out vec4 v_position4f;
|
||||
|
||||
#ifdef COMPILE_FOG_LIGHT_SHAFTS
|
||||
out vec2 v_positionClip2f;
|
||||
out vec3 v_positionClip3f;
|
||||
#endif
|
||||
|
||||
#ifdef COMPILE_TEXTURE_ATTRIB
|
||||
@ -98,6 +98,6 @@ void main() {
|
||||
#endif
|
||||
|
||||
#ifdef COMPILE_FOG_LIGHT_SHAFTS
|
||||
v_positionClip2f = gl_Position.xy / gl_Position.w;
|
||||
v_positionClip3f = gl_Position.xyw;
|
||||
#endif
|
||||
}
|
||||
|
@ -85,6 +85,8 @@ layout(std140) uniform u_worldLightingData {
|
||||
uniform sampler2D u_environmentMap;
|
||||
uniform sampler2D u_brdfLUT;
|
||||
|
||||
#EAGLER INCLUDE (4) "eagler:glsl/deferred/lib/branchless_comparison.glsl"
|
||||
|
||||
#define GLASS_ROUGHNESS 0.15
|
||||
#define GLASS_F0 0.4
|
||||
|
||||
@ -126,14 +128,14 @@ vec2(-0.077, 0.995), vec2(0.998, 0.015),
|
||||
vec2(-0.116, -0.987), vec2(-0.916, 0.359),
|
||||
vec2(-0.697, -0.511), vec2(0.740, -0.612),
|
||||
vec2(0.675, 0.682));
|
||||
#define SMOOTH_SHADOW_SAMPLES 1.0 / 8.0
|
||||
#define SMOOTH_SHADOW_RADIUS 0.00075
|
||||
#define SMOOTH_SHADOW_SAMPLES (1.0 / 8.0)
|
||||
#define SMOOTH_SHADOW_RADIUS 0.000488
|
||||
#define SMOOTH_SHADOW_POISSON_SAMPLE(idx, tex, lod, vec3Pos, accum, tmpVec2)\
|
||||
tmpVec2 = vec3Pos.xy + POISSON_DISK[idx] * SMOOTH_SHADOW_RADIUS;\
|
||||
tmpVec2 = clamp(tmpVec2, vec2(0.001), vec2(0.999));\
|
||||
tmpVec2.y += lod;\
|
||||
tmpVec2.y *= SUN_SHADOW_MAP_FRAC;\
|
||||
accum += textureLod(tex, vec3(tmpVec2, vec3Pos.z), 0.0) * SMOOTH_SHADOW_SAMPLES;
|
||||
accum += textureLod(tex, vec3(tmpVec2, vec3Pos.z + 0.0001), 0.0);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -184,16 +186,15 @@ void main() {
|
||||
float skyLight = max(lightmapCoords2f.g * 2.0 - 1.0, 0.0);
|
||||
float shadowSample = 1.0;
|
||||
vec4 shadowWorldPos4f = worldPosition4f;
|
||||
shadowWorldPos4f.xyz += normalVector3f * 0.05;
|
||||
shadowWorldPos4f.xyz += normalVector3f * 0.1;
|
||||
|
||||
vec4 shadowTexPos4f;
|
||||
vec2 tmpVec2;
|
||||
for(;;) {
|
||||
shadowTexPos4f = u_sunShadowMatrixLOD04f * shadowWorldPos4f;
|
||||
if(shadowTexPos4f.xyz == clamp(shadowTexPos4f.xyz, vec3(0.005), vec3(0.995))) {
|
||||
shadowSample = textureLod(u_sunShadowDepthTexture, vec3(shadowTexPos4f.xy * vec2(1.0, SUN_SHADOW_MAP_FRAC), shadowTexPos4f.z), 0.0);
|
||||
shadowSample = textureLod(u_sunShadowDepthTexture, vec3(shadowTexPos4f.xy * vec2(1.0, SUN_SHADOW_MAP_FRAC), shadowTexPos4f.z + 0.0001), 0.0);
|
||||
#ifdef COMPILE_SUN_SHADOW_SMOOTH
|
||||
shadowSample *= SMOOTH_SHADOW_SAMPLES;
|
||||
SMOOTH_SHADOW_POISSON_SAMPLE(0, u_sunShadowDepthTexture, 0.0, shadowTexPos4f.xyz, shadowSample, tmpVec2)
|
||||
SMOOTH_SHADOW_POISSON_SAMPLE(1, u_sunShadowDepthTexture, 0.0, shadowTexPos4f.xyz, shadowSample, tmpVec2)
|
||||
SMOOTH_SHADOW_POISSON_SAMPLE(2, u_sunShadowDepthTexture, 0.0, shadowTexPos4f.xyz, shadowSample, tmpVec2)
|
||||
@ -201,7 +202,7 @@ void main() {
|
||||
SMOOTH_SHADOW_POISSON_SAMPLE(4, u_sunShadowDepthTexture, 0.0, shadowTexPos4f.xyz, shadowSample, tmpVec2)
|
||||
SMOOTH_SHADOW_POISSON_SAMPLE(5, u_sunShadowDepthTexture, 0.0, shadowTexPos4f.xyz, shadowSample, tmpVec2)
|
||||
SMOOTH_SHADOW_POISSON_SAMPLE(6, u_sunShadowDepthTexture, 0.0, shadowTexPos4f.xyz, shadowSample, tmpVec2)
|
||||
shadowSample = max(shadowSample * 2.0 - 1.0, 0.0);
|
||||
shadowSample *= SMOOTH_SHADOW_SAMPLES;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
@ -238,7 +239,7 @@ void main() {
|
||||
|
||||
for(;;) {
|
||||
float dst2 = dot(worldPosition4f.xyz, worldPosition4f.xyz);
|
||||
if(dst2 > 16.0) {
|
||||
if(dst2 > 25.0) {
|
||||
break;
|
||||
}
|
||||
vec3 reflectDir = reflect(worldDirection4f.xyz, normalVector3f);
|
||||
@ -252,12 +253,13 @@ void main() {
|
||||
vec4 sample2 = textureLod(u_environmentMap, reflectDir.xz * vec2(0.5, -0.25) + vec2(0.5, 0.75), 0.0);
|
||||
envMapSample4f = vec4(mix(sample1.rgb, sample2.rgb, smoothstep(0.0, 1.0, reflectDir.y * -12.5 + 0.5)).rgb, min(sample1.a, sample2.a));
|
||||
}else {
|
||||
reflectDir.xz = reflectDir.xz * vec2(0.5, reflectDir.y > 0.0 ? 0.25 : -0.25);
|
||||
reflectDir.xz += vec2(0.5, reflectDir.y > 0.0 ? 0.25 : 0.75);
|
||||
reflectDir.xz = reflectDir.xz * vec2(0.5, COMPARE_GT_C_C(reflectDir.y, 0.0, 0.25, -0.25));
|
||||
reflectDir.xz += vec2(0.5, COMPARE_GT_C_C(reflectDir.y, 0.0 , 0.25, 0.75));
|
||||
envMapSample4f = textureLod(u_environmentMap, reflectDir.xz, 0.0);
|
||||
}
|
||||
if(envMapSample4f.a > 0.0) {
|
||||
lightColor3f += eaglercraftIBL_Specular_Glass(envMapSample4f.rgb, worldDirection4f.xyz, normalVector3f) * (1.0 - sqrt(dst2) * 0.25);
|
||||
envMapSample4f.a += min(lightmapCoords2f.g * 2.0, 1.0) * (1.0 - envMapSample4f.a);
|
||||
if(envMapSample4f.a == 1.0) {
|
||||
lightColor3f += eaglercraftIBL_Specular_Glass(envMapSample4f.rgb * envMapSample4f.a, worldDirection4f.xyz, normalVector3f) * (1.0 - sqrt(dst2) * 0.2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -268,6 +270,7 @@ void main() {
|
||||
|
||||
vec3 dlightDist3f, dlightDir3f, dlightColor3f;
|
||||
int safeLightCount = u_dynamicLightCount1i > 12 ? 0 : u_dynamicLightCount1i; // hate this
|
||||
float cm;
|
||||
for(int i = 0; i < safeLightCount; ++i) {
|
||||
dlightDist3f = u_dynamicLightArray[i].u_lightPosition4f.xyz - worldPosition4f.xyz;
|
||||
dlightDir3f = normalize(dlightDist3f);
|
||||
@ -275,9 +278,11 @@ void main() {
|
||||
continue;
|
||||
}
|
||||
dlightColor3f = u_dynamicLightArray[i].u_lightColor4f.rgb / dot(dlightDist3f, dlightDist3f);
|
||||
if(dlightColor3f.r + dlightColor3f.g + dlightColor3f.b < 0.025) {
|
||||
cm = dlightColor3f.r + dlightColor3f.g + dlightColor3f.b;
|
||||
if(cm < 0.025) {
|
||||
continue;
|
||||
}
|
||||
dlightColor3f *= ((cm - 0.025) / cm);
|
||||
lightColor3f += eaglercraftLighting_Glass(dlightColor3f, -worldDirection4f.xyz, dlightDir3f, normalVector3f) * u_blockSkySunDynamicLightFac4f.w;
|
||||
}
|
||||
|
||||
@ -287,7 +292,7 @@ void main() {
|
||||
|
||||
float fogFade = 0.0;
|
||||
if(u_fogParameters4f.x > 0.0) {
|
||||
float atmos = u_fogParameters4f.x >= 4.0 ? 4.0 : 0.0;
|
||||
float atmos = COMPARE_LT_C_C(u_fogParameters4f.x, 4.0, 0.0, 4.0);
|
||||
float type = u_fogParameters4f.x - atmos;
|
||||
fogFade = mix(u_fogColorDark4f.a, u_fogColorLight4f.a, lightmapCoords2f.g);
|
||||
|
||||
|
@ -53,7 +53,7 @@ void main() {
|
||||
#endif
|
||||
#ifdef DEBUG_VIEW_3
|
||||
vec4 color4f = textureLod(u_texture0, v_position2f, 0.0);
|
||||
output4f = vec4(color4f.b > 0.99 ? 1.0 : 0.0, color4f.a, 0.0, 1.0);
|
||||
output4f = vec4((color4f.a - (color4f.a > 0.5 ? 0.5 : 0.0)) * 2.0, color4f.a > 0.5 ? 1.0 : 0.0, color4f.b > 0.99 ? 1.0 : 0.0, 1.0);
|
||||
#endif
|
||||
#ifdef DEBUG_VIEW_4
|
||||
output4f = vec4(vec3(clamp((textureLod(u_texture0, v_position2f, 0.0).r - u_depthSliceStartEnd2f.x) * u_depthSliceStartEnd2f.y, 0.0, 1.0)), 1.0);
|
||||
|
@ -25,5 +25,5 @@ in vec2 v_position2f;
|
||||
uniform sampler2D u_depthTexture;
|
||||
|
||||
void main() {
|
||||
gl_FragDepth = textureLod(u_depthTexture, v_position2f, 0.0).r <= 0.0000001 ? 0.0 : 1.0;
|
||||
gl_FragDepth = textureLod(u_depthTexture, v_position2f, 0.0).r == 0.0 ? 0.0 : 1.0;
|
||||
}
|
||||
|
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2025 lax1dude. All Rights Reserved.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
// Assuming modern GPUs probably implement clamp, max, and ciel without branches
|
||||
|
||||
// value1 > value2 ? 1.0 : 0.0
|
||||
#define COMPARE_GT_0_1(value1, value2) clamp(ceil(value1 - value2), 0.0, 1.0)
|
||||
|
||||
// value1 > value2 ? N : 0.0
|
||||
#define COMPARE_GT_0_ANY(value1, value2) max(ceil(value1 - value2), 0.0)
|
||||
|
||||
// value1 < value2 ? 1.0 : 0.0
|
||||
#define COMPARE_LT_0_1(value1, value2) clamp(ceil(value2 - value1), 0.0, 1.0)
|
||||
|
||||
// value1 < value2 ? N : 0.0
|
||||
#define COMPARE_LT_0_ANY(value1, value2) max(ceil(value2 - value1), 0.0)
|
||||
|
||||
// value1 > value2 ? ifGT : ifLT
|
||||
#define COMPARE_GT_C_C(value1, value2, ifGT, ifLT) (COMPARE_GT_0_1(value1, value2) * (ifGT - ifLT) + ifLT)
|
||||
|
||||
// value1 < value2 ? ifLT : ifGT
|
||||
#define COMPARE_LT_C_C(value1, value2, ifLT, ifGT) (COMPARE_LT_0_1(value1, value2) * (ifLT - ifGT) + ifGT)
|
@ -119,4 +119,4 @@ vec3 eaglercraftIBL_Specular(in vec3 albedo, in vec3 envMapSample, in vec3 viewD
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
@ -84,7 +84,7 @@ float shadow(in vec3 coords) {
|
||||
void main() {
|
||||
output1f = 0.0;
|
||||
float depth = textureLod(u_gbufferDepthTexture, v_position2f, 0.0).r;
|
||||
if(depth < 0.00001) {
|
||||
if(depth == 0.0) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -47,7 +47,7 @@ void main() {
|
||||
vec3 materialData3f;
|
||||
|
||||
float depth = textureLod(u_gbufferDepthTexture, v_position2f, 0.0).r;
|
||||
if(depth < 0.00001) {
|
||||
if(depth == 0.0) {
|
||||
discard;
|
||||
}
|
||||
|
||||
@ -59,11 +59,14 @@ void main() {
|
||||
worldSpacePosition = u_inverseViewMatrix4f * worldSpacePosition;
|
||||
vec3 lightDist = (worldSpacePosition.xyz / worldSpacePosition.w) - u_lightPosition3f;
|
||||
vec3 color3f = u_lightColor3f / dot(lightDist, lightDist);
|
||||
float cm = color3f.r + color3f.g + color3f.b;
|
||||
|
||||
if(color3f.r + color3f.g + color3f.b < 0.025) {
|
||||
if(cm < 0.025) {
|
||||
discard;
|
||||
}
|
||||
|
||||
color3f *= ((cm - 0.025) / cm);
|
||||
|
||||
vec4 sampleVar4f = textureLod(u_gbufferColorTexture, v_position2f, 0.0);
|
||||
diffuseColor3f.rgb = sampleVar4f.rgb;
|
||||
lightmapCoords2f.x = sampleVar4f.a;
|
||||
|
@ -37,6 +37,9 @@ uniform mat4 u_inverseProjectionMatrix4f;
|
||||
#ifdef COMPILE_SUN_SHADOW
|
||||
uniform sampler2D u_sunShadowTexture;
|
||||
#endif
|
||||
#ifdef COMPILE_SUBSURFACE_SCATTERING
|
||||
uniform sampler2D u_subsurfaceScatteringTexture;
|
||||
#endif
|
||||
|
||||
uniform vec3 u_sunDirection3f;
|
||||
uniform vec3 u_sunColor3f;
|
||||
@ -49,22 +52,64 @@ void main() {
|
||||
vec3 normalVector3f;
|
||||
vec2 lightmapCoords2f;
|
||||
vec3 materialData3f;
|
||||
vec4 sampleVar4f;
|
||||
|
||||
#ifdef COMPILE_SUBSURFACE_SCATTERING
|
||||
float depth = textureLod(u_gbufferDepthTexture, v_position2f, 0.0).r;
|
||||
if(depth == 0.0) {
|
||||
discard;
|
||||
}
|
||||
sampleVar4f = textureLod(u_gbufferColorTexture, v_position2f, 0.0);
|
||||
diffuseColor3f.rgb = sampleVar4f.rgb;
|
||||
diffuseColor3f *= diffuseColor3f;
|
||||
lightmapCoords2f.x = sampleVar4f.a;
|
||||
#endif
|
||||
|
||||
#ifdef COMPILE_SUBSURFACE_SCATTERING
|
||||
float subsurfValue = textureLod(u_subsurfaceScatteringTexture, v_position2f, 0.0).r;
|
||||
subsurfValue *= subsurfValue;
|
||||
output4f = vec4(subsurfValue * u_sunColor3f * diffuseColor3f * 0.125, 0.0);
|
||||
#endif
|
||||
|
||||
#ifdef COMPILE_SUN_SHADOW
|
||||
#ifdef COMPILE_COLORED_SHADOW
|
||||
vec4 shadow = textureLod(u_sunShadowTexture, v_position2f, 0.0);
|
||||
if(shadow.a < 0.05) {
|
||||
#ifndef COMPILE_SUBSURFACE_SCATTERING
|
||||
discard;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
vec3 shadow = vec3(textureLod(u_sunShadowTexture, v_position2f, 0.0).r);
|
||||
#ifndef COMPILE_SUBSURFACE_SCATTERING
|
||||
if(shadow.r < 0.05) {
|
||||
#ifndef COMPILE_SUBSURFACE_SCATTERING
|
||||
discard;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
vec4 sampleVar4f = textureLod(u_gbufferNormalTexture, v_position2f, 0.0);
|
||||
#ifndef COMPILE_SUBSURFACE_SCATTERING
|
||||
float depth = textureLod(u_gbufferDepthTexture, v_position2f, 0.0).r;
|
||||
#endif
|
||||
|
||||
#ifndef COMPILE_SUN_SHADOW
|
||||
if(depth == 0.0) {
|
||||
#ifndef COMPILE_SUBSURFACE_SCATTERING
|
||||
discard;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
sampleVar4f = textureLod(u_gbufferNormalTexture, v_position2f, 0.0);
|
||||
|
||||
#ifndef COMPILE_SUN_SHADOW
|
||||
vec3 shadow = vec3(sampleVar4f.a, 0.0, 0.0);
|
||||
@ -77,17 +122,12 @@ void main() {
|
||||
normalVector3f.xyz = sampleVar4f.rgb * 2.0 - 1.0;
|
||||
lightmapCoords2f.y = sampleVar4f.a;
|
||||
|
||||
float depth = textureLod(u_gbufferDepthTexture, v_position2f, 0.0).r;
|
||||
|
||||
#ifndef COMPILE_SUN_SHADOW
|
||||
if(depth < 0.00001) {
|
||||
discard;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef COMPILE_SUBSURFACE_SCATTERING
|
||||
sampleVar4f = textureLod(u_gbufferColorTexture, v_position2f, 0.0);
|
||||
diffuseColor3f.rgb = sampleVar4f.rgb;
|
||||
diffuseColor3f *= diffuseColor3f;
|
||||
lightmapCoords2f.x = sampleVar4f.a;
|
||||
#endif
|
||||
materialData3f = textureLod(u_gbufferMaterialTexture, v_position2f, 0.0).rgb;
|
||||
|
||||
vec3 worldSpaceNormal = normalize(mat3(u_inverseViewMatrix4f) * normalVector3f);
|
||||
@ -97,6 +137,15 @@ void main() {
|
||||
worldSpacePosition = u_inverseProjectionMatrix4f * worldSpacePosition;
|
||||
worldSpacePosition = u_inverseViewMatrix4f * vec4(worldSpacePosition.xyz / worldSpacePosition.w, 0.0);
|
||||
|
||||
diffuseColor3f *= diffuseColor3f;
|
||||
output4f = vec4(eaglercraftLighting(diffuseColor3f, u_sunColor3f * shadow.rgb, normalize(-worldSpacePosition.xyz), u_sunDirection3f, worldSpaceNormal, materialData3f), 0.0);
|
||||
}
|
||||
#ifdef COMPILE_SUBSURFACE_SCATTERING
|
||||
output4f.rgb +=
|
||||
#else
|
||||
output4f = vec4(
|
||||
#endif
|
||||
eaglercraftLighting(diffuseColor3f, u_sunColor3f * shadow.rgb, normalize(-worldSpacePosition.xyz), u_sunDirection3f, worldSpaceNormal, materialData3f)
|
||||
#ifdef COMPILE_SUBSURFACE_SCATTERING
|
||||
* (1.0 - subsurfValue * 0.0625);
|
||||
#else
|
||||
, 0.0);
|
||||
#endif
|
||||
}
|