Skip to content
Merged
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
2 changes: 1 addition & 1 deletion .checkstyle/suppressions.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<!DOCTYPE suppressions PUBLIC "-//Checkstyle//DTD SuppressionFilter Configuration 1.2//EN" "http://checkstyle.org/dtds/suppressions_1_2.dtd">
<suppressions>
<!-- don't require javadocs on platform modules -->
<suppress files="example[\\/](bukkit|minestom)[\\/](api|json|proto|common)[\\/]src[\\/]main[\\/]java[\\/].*" checks="(FilteringWriteTag|MissingJavadoc.*)"/>
<suppress files="example[\\/](bukkit|minestom)[\\/](api|json|proto|common|nms)[\\/]src[\\/]main[\\/]java[\\/].*" checks="(FilteringWriteTag|MissingJavadoc.*)"/>

<!-- ignore illegal import in loader -->
<suppress files="extra[\\/]loader[\\/]src[\\/]main[\\/]java[\\/].*" checks="(IllegalImport)"/>
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
uses: actions/setup-java@v3
with:
distribution: "zulu"
java-version: 8
java-version: 21

- name: Gradle Build
run: ./gradlew build
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* This file is part of Apollo, licensed under the MIT License.
*
* Copyright (c) 2026 Moonsworth
*
* 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.
*/
package com.lunarclient.apollo.module.cosmetic;

import com.lunarclient.apollo.module.cosmetic.options.BodyOptions;
import com.lunarclient.apollo.module.cosmetic.options.CloakOptions;
import com.lunarclient.apollo.module.cosmetic.options.CosmeticOptions;
import com.lunarclient.apollo.module.cosmetic.options.HatOptions;
import com.lunarclient.apollo.module.cosmetic.options.PetOptions;
import lombok.Builder;
import lombok.Getter;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.Range;

/**
* Represents a single cosmetic with optional per-type display settings.
*
* @since 1.2.6
*/
@Getter
@Builder
public final class Cosmetic {

/**
* Returns the Lunar Client cosmetic id for this entry.
*
* <p>The value must be greater than 0.</p>
*
* @return the cosmetic id
* @since 1.2.6
*/
@Range(from = 1, to = Integer.MAX_VALUE) int id;

/**
* Returns optional cosmetic display options for this cosmetic id.
*
* <p>Expected concrete types are {@link HatOptions}, {@link CloakOptions}, {@link PetOptions}, or
* {@link BodyOptions}.</p>
*
* @return cosmetic options, or {@code null}
* @since 1.2.6
*/
@Nullable CosmeticOptions options;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
/*
* This file is part of Apollo, licensed under the MIT License.
*
* Copyright (c) 2026 Moonsworth
*
* 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.
*/
package com.lunarclient.apollo.module.cosmetic;

import com.lunarclient.apollo.common.location.ApolloBlockLocation;
import com.lunarclient.apollo.module.ApolloModule;
import com.lunarclient.apollo.module.ModuleDefinition;
import com.lunarclient.apollo.module.cosmetic.options.BodyOptions;
import com.lunarclient.apollo.module.cosmetic.options.CloakOptions;
import com.lunarclient.apollo.module.cosmetic.options.CosmeticOptions;
import com.lunarclient.apollo.module.cosmetic.options.HatOptions;
import com.lunarclient.apollo.module.cosmetic.options.PetOptions;
import com.lunarclient.apollo.recipients.Recipients;
import java.util.List;
import java.util.UUID;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.Range;

/**
* Represents the cosmetic module.
*
* @since 1.2.6
*/
@ApiStatus.NonExtendable
@ModuleDefinition(id = "cosmetic", name = "Cosmetic")
public abstract class CosmeticModule extends ApolloModule {

/**
* Equips the provided cosmetics on an NPC for the given {@link Recipients}.
*
* @param recipients the recipients that are receiving the packet
* @param npcUuid the {@link UUID} of the NPC to equip the cosmetics on
* @param cosmetics the cosmetics to equip, including optional {@link CosmeticOptions} per entry
* ({@link HatOptions}, {@link CloakOptions}, {@link PetOptions}, or {@link BodyOptions})
* @since 1.2.6
*/
public abstract void equipNpcCosmetics(Recipients recipients, UUID npcUuid, List<Cosmetic> cosmetics);

/**
* Unequips the provided cosmetics from an NPC for the given {@link Recipients}.
*
* @param recipients the recipients that are receiving the packet
* @param npcUuid the {@link UUID} of the NPC to unequip the cosmetics from
* @param cosmeticIds the list of cosmetic ids to unequip
* @since 1.2.6
*/
public abstract void unequipNpcCosmetics(Recipients recipients, UUID npcUuid, List<Integer> cosmeticIds);

/**
* Resets all cosmetics on an NPC for the given {@link Recipients}.
*
* @param recipients the recipients that are receiving the packet
* @param npcUuid the {@link UUID} of the NPC to reset the cosmetics on
* @since 1.2.6
*/
public abstract void resetNpcCosmetics(Recipients recipients, UUID npcUuid);

/**
* Displays a spray for the given {@link Recipients}.
*
* @param recipients the recipients that are receiving the packet
* @param spray the spray to display (durations under one second are raised to one second before sending)
* @since 1.2.6
*/
public abstract void displaySpray(Recipients recipients, Spray spray);

/**
* Removes every instance of a spray id for the given {@link Recipients}.
*
* <p>The spray id must be greater than 0.</p>
*
* @param recipients the recipients that are receiving the packet
* @param sprayId the spray cosmetic id
* @since 1.2.6
*/
public abstract void removeSpray(Recipients recipients, @Range(from = 1, to = Integer.MAX_VALUE) int sprayId);

/**
* Removes every instance of a spray id at a specific block for the given {@link Recipients}.
*
* <p>The spray id must be greater than 0. If {@code location} is {@code null}, every
* instance of the spray id is removed regardless of position.</p>
*
* @param recipients the recipients that are receiving the packet
* @param sprayId the spray cosmetic id
* @param location the block location of the spray to remove, or {@code null} to remove all
* @since 1.2.6
*/
public abstract void removeSpray(Recipients recipients, @Range(from = 1, to = Integer.MAX_VALUE) int sprayId, @Nullable ApolloBlockLocation location);

/**
* Resets all server sprays for the given {@link Recipients}.
*
* @param recipients the recipients that are receiving the packet
* @since 1.2.6
*/
public abstract void resetSprays(Recipients recipients);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*
* This file is part of Apollo, licensed under the MIT License.
*
* Copyright (c) 2026 Moonsworth
*
* 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.
*/
package com.lunarclient.apollo.module.cosmetic;

import com.lunarclient.apollo.common.location.ApolloBlockLocation;
import com.lunarclient.apollo.module.packetenrichment.raytrace.Direction;
import java.time.Duration;
import lombok.Builder;
import lombok.Getter;
import org.jetbrains.annotations.Range;

/**
* Represents a spray.
*
* <p>Sprays are client-local and validated against loaded chunks;
* they're removed when their backing chunk unloads and won't reappear
* unless the server resends the spray packet.</p>
*
* @since 1.2.6
*/
@Getter
@Builder
public final class Spray {

/**
* Returns the Lunar Client spray cosmetic id.
*
* <p>The value must be greater than 0.</p>
*
* @return the spray cosmetic id
* @since 1.2.6
*/
@Range(from = 1, to = Integer.MAX_VALUE) int sprayId;

/**
* Returns the {@link ApolloBlockLocation} of the block the spray is placed on.
*
* @return the block location
* @since 1.2.6
*/
ApolloBlockLocation location;

/**
* Returns the {@link Direction} indicating which side the spray faces.
*
* @return the facing direction
* @since 1.2.6
*/
Direction facing;

/**
* Returns the spray rotation in degrees on the client.
*
* @return the rotation in degrees
* @since 1.2.6
*/
@Builder.Default
float rotation = 0f;

/**
* Returns the {@link Duration} for how long the spray remains visible on the client.
*
* @return the display duration
* @since 1.2.6
*/
@Builder.Default
Duration duration = Duration.ofSeconds(30);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* This file is part of Apollo, licensed under the MIT License.
*
* Copyright (c) 2026 Moonsworth
*
* 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.
*/
package com.lunarclient.apollo.module.cosmetic.options;

import com.lunarclient.apollo.module.cosmetic.Cosmetic;
import lombok.Builder;
import lombok.Getter;

/**
* Represents body cosmetic display settings for use with {@link Cosmetic}.
*
* @since 1.2.6
*/
@Getter
@Builder
public final class BodyOptions extends CosmeticOptions {

/**
* Returns whether the body cosmetic should render on top of an equipped chestplate when present.
*
* @return {@code true} to draw over the chestplate, {@code false} otherwise
* @since 1.2.6
*/
@Builder.Default
boolean showOverChestplate = true;

/**
* Returns whether the body cosmetic should render on top of equipped leggings when present.
*
* @return {@code true} to draw over the leggings, {@code false} otherwise
* @since 1.2.6
*/
@Builder.Default
boolean showOverLeggings = true;

/**
* Returns whether the body cosmetic should render on top of equipped boots when present.
*
* @return {@code true} to draw over the boots, {@code false} otherwise
* @since 1.2.6
*/
@Builder.Default
boolean showOverBoots = true;

}
Loading
Loading