Skip to content
Merged

dev #106

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/pr_assignment_config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
addReviewers: true
reviewers:
- Aliorpse
numberOfReviewers: 1
12 changes: 12 additions & 0 deletions .github/workflows/pr_assignment.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
name: PR Assignment
on:
pull_request:
types: [opened, ready_for_review]

jobs:
add-reviews:
runs-on: ubuntu-latest
steps:
- uses: kentaro-m/auto-assign-action@v2.0.1
with:
configuration-path: ".github/pr_assignment_config.yml"
36 changes: 31 additions & 5 deletions .github/workflows/pr_validation.yml
Original file line number Diff line number Diff line change
@@ -1,18 +1,41 @@
name: PR Validation
name: PR ABI Validation

on:
pull_request:
branches: [ main ]
pull_request_review:
types: [submitted]

jobs:
validate:
if: github.event.review.state == 'approved'
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}

- name: Grant execute permission to gradlew
run: chmod +x ./gradlew
- name: Check Review Status
uses: actions/github-script@v7
with:
script: |
const { data: reviews } = await github.rest.pulls.listReviews({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.payload.pull_request.number,
});

const latestReviews = {};
reviews.forEach(r => {
latestReviews[r.user.login] = r.state;
});

const states = Object.values(latestReviews);
const allApproved = states.every(state => state === 'APPROVED') && states.length > 0;

if (!allApproved) {
console.log("Skipping ABI validation because not all reviewers approved.");
process.exit(0);
}

- name: Set up JDK
uses: actions/setup-java@v4
Expand All @@ -21,5 +44,8 @@ jobs:
java-version: 21
cache: 'gradle'

- name: Grant execute permission
run: chmod +x ./gradlew

- name: ABI Validation
run: ./gradlew checkLegacyAbi -Pfull-build=true --no-configuration-cache
16 changes: 7 additions & 9 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,10 @@ Welcome to contribute to this project! To ensure an effective collaboration, ple

## Pull Requests

- Open an issue to discuss changes before coding.
- Fork the repository and create a new branch named like "feat/my-feature".
- Write your codes and tests in the new branch.
- Follow [Kotlin Coding Conventions](https://kotlinlang.org/docs/coding-conventions.html).
- add `Pfull-build=true` to abi-validating related tasks.
- run `./gradlew checkLegacyAbi` to check your changes. If including a breaking change, run `./gradlew updateLegacyAbi`.
- Use concise, descriptive PR titles with prefixes like `feat:` or `fix:`.
- Link PRs to issues with `Closes #xx`.
- Create a pull request to the `main` branch.
1. Open an issue to discuss changes.
2. Fork the repository and create a new branch named like `feat/my-feature`, code in it.
3. add `Pfull-build=true` to abi-validating related tasks, for full build is disabled to boost dev build speed.
4. run `./gradlew checkLegacyAbi` to check your changes. If including a breaking change, run `./gradlew updateLegacyAbi`.
5. When creating PR, use a concise, descriptive PR title with prefixes like `feat:` or `fix:`.Please open the PR against the `main` branch.


26 changes: 23 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,25 @@
# mcutils

[![CodeFactor](https://www.codefactor.io/repository/github/aliorpse/mcutils/badge)](https://www.codefactor.io/repository/github/aliorpse/mcutils)
[![Maven Central](https://maven-badges.sml.io/sonatype-central/tech.aliorpse.mcutils/mcutils-shared/badge.svg)](https://central.sonatype.com/artifact/tech.aliorpse.mcutils/mcutils-shared)
![Maven Central](https://maven-badges.sml.io/sonatype-central/tech.aliorpse.mcutils/mcutils-shared/badge.svg)
[![View on DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/Aliorpse/mcutils)

A Kotlin multiplatform library provides utility functions for Minecraft-related queries.
mcutils is a lightweight **Kotlin Multiplatform** library for Minecraft Java related queries, such as server
ping/management, fetching player profile, etc.

## Supported platforms

* **Kotlin/JVM**
* **Kotlin/JS, WasmJS** on
* nodejs
* browser *(except modules that depend on ktor-network, see [build.gradle.kts](build.gradle.kts) for more details)*
* **Kotlin/Native** on
* linuxX64 (X64/Arm64)
* mingw (X64)
* ios (X64/Arm64)
* iosSimulator (Arm64)
* macos (X64/Arm64)
* androidNative (X64/Arm64)

## Modules

Expand All @@ -13,4 +28,9 @@ A Kotlin multiplatform library provides utility functions for Minecraft-related
- [Remote Console (RCON)](mcutils-rcon/README.md): Execute commands remotely on the server.
- [Player Profile](mcutils-player/README.md): Retrieve player UUIDs and profiles.

Check out the project's [dokka](https://aliorpse.github.io/mcutils/) for the full API reference.
Click on the links for module-specific documents, or check out the project's [dokka](https://aliorpse.github.io/mcutils/) for the full API reference.


## Contributing

Please refer to [CONTRIBUTING.md](CONTRIBUTING.md) for more details.
7 changes: 4 additions & 3 deletions mcutils-msmp/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Minecraft Server Management Protocol (MSMP)

`tech.aliorpse.mcutils:mcutils-msmp:$version`
`tech.aliorpse.mcutils:mcutils-msmp`

> [!tip]
> This module requires a Ktor client engine (e.g., `ktor-client-cio`).
Expand Down Expand Up @@ -29,7 +29,8 @@ client.use { client ->
val players = client.players.get()
println("Online players: ${players.size}")

// Await client to be closed (e.g., server stopping or manual close)
// Wait for the client to close (e.g., server stopping or manual close)
// You could use `coroutineScope { ... }` for the same effect, but you know it will add an indentation level.
client.await()
}
```
Expand Down Expand Up @@ -76,7 +77,7 @@ client.on<PlayerJoinedEvent> {
val event = client.awaitEvent<ServerStartedEvent>()
```

You don't need to re-register listeners after reconnection. eventFlow will be empty when reconnecting.
Note: Event subscriptions persist across reconnections, but no events are buffered during the disconnected period.

### Lifecycle

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import tech.aliorpse.mcutils.api.MsmpState
import tech.aliorpse.mcutils.entity.ServerStoppingEvent
import tech.aliorpse.mcutils.internal.util.DispatchersIO
import tech.aliorpse.mcutils.internal.util.WebSocketClientProvider.webSocketClient
import tech.aliorpse.mcutils.internal.util.isBrowser
import kotlin.math.min
import kotlin.math.pow
import kotlin.random.Random
Expand Down Expand Up @@ -143,7 +144,11 @@ internal class MsmpLifecycleManager(
*/
private suspend fun connectSession(): Boolean = coroutineScope {
val session = webSocketClient.webSocketSession(target) {
header(HttpHeaders.Authorization, "Bearer $token")
if (isBrowser) {
header(HttpHeaders.SecWebSocketProtocol, "minecraft-v1,$token")
} else {
header(HttpHeaders.Authorization, "Bearer $token")
}
timeout { connectTimeoutMillis = config.connectTimeout }
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package tech.aliorpse.mcutils.internal.util

internal expect val isBrowser: Boolean
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package tech.aliorpse.mcutils.internal.util

internal actual val isBrowser: Boolean =
js("typeof window !== 'undefined' && typeof window.document !== 'undefined'")
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package tech.aliorpse.mcutils.internal.util

internal actual val isBrowser: Boolean = false
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package tech.aliorpse.mcutils.internal.util

internal actual val isBrowser: Boolean = false
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package tech.aliorpse.mcutils.internal.util

@OptIn(ExperimentalWasmJsInterop::class)
internal actual val isBrowser: Boolean =
js("typeof window !== 'undefined' && typeof window.document !== 'undefined'")
2 changes: 1 addition & 1 deletion mcutils-player/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Player Profile

`tech.aliorpse.mcutils:mcutils-player:$version`
`tech.aliorpse.mcutils:mcutils-player`

> [!tip]
> This module requires a Ktor client engine (e.g., `ktor-client-cio`).
Expand Down
2 changes: 1 addition & 1 deletion mcutils-rcon/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Remote Console (RCON)

`tech.aliorpse.mcutils:mcutils-rcon:$version`
`tech.aliorpse.mcutils:mcutils-rcon`

## Common Usage

Expand Down
2 changes: 1 addition & 1 deletion mcutils-server-status/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Server Status

`tech.aliorpse.mcutils:mcutils-server-status:$version`
`tech.aliorpse.mcutils:mcutils-server-status`

> [!warning]
> Native targets do not yet support an SRV record implementation. Setting `enableSrv = true` will not have any effect on these platforms.
Expand Down