Merge branch 'main' of https://gitea.codersquack.nl/NeoFlock/NeoComputers
This commit is contained in:
@@ -34,6 +34,7 @@ object Blocks {
|
||||
val CASE_BLOCK: RegistrySupplier<Block> = BaseBlock.register("case") { CaseBlock() }
|
||||
val REDSTONEIO_BLOCK: RegistrySupplier<Block> = BaseBlock.register("redio") { RedstoneIOBlock() }
|
||||
val CABLE_BLOCK: RegistrySupplier<Block> = BaseBlock.register("cable") { CableBlock() }
|
||||
val RELAY_BLOCK: RegistrySupplier<Block> = BaseBlock.register("relay") { RelayBlock() }
|
||||
|
||||
fun registerBlockItems() {
|
||||
BLOCKS.forEach(Consumer { sup: RegistrySupplier<Block> ->
|
||||
|
||||
170
src/main/kotlin/org/neoflock/neocomputers/block/RelayBlock.kt
Normal file
170
src/main/kotlin/org/neoflock/neocomputers/block/RelayBlock.kt
Normal file
@@ -0,0 +1,170 @@
|
||||
package org.neoflock.neocomputers.block
|
||||
|
||||
import dev.architectury.registry.menu.MenuRegistry
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.core.HolderLookup
|
||||
import net.minecraft.core.NonNullList
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraft.network.FriendlyByteBuf
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.world.ContainerHelper
|
||||
import net.minecraft.world.InteractionResult
|
||||
import net.minecraft.world.MenuProvider
|
||||
import net.minecraft.world.entity.player.Inventory
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.level.Level
|
||||
import net.minecraft.world.level.block.SoundType
|
||||
import net.minecraft.world.level.block.entity.BlockEntity
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import net.minecraft.world.phys.BlockHitResult
|
||||
import org.neoflock.neocomputers.entity.BlockEntities
|
||||
import org.neoflock.neocomputers.entity.ComponentUser
|
||||
import org.neoflock.neocomputers.gui.menu.RelayMenu
|
||||
import org.neoflock.neocomputers.item.RelayUpgrade
|
||||
import org.neoflock.neocomputers.network.ConventionalNetworkDevice
|
||||
import org.neoflock.neocomputers.network.DeviceNode
|
||||
import org.neoflock.neocomputers.network.Networking
|
||||
import org.neoflock.neocomputers.network.NodeSynchronizer
|
||||
import org.neoflock.neocomputers.utils.GenericContainer
|
||||
|
||||
class RelayEntity(blockPos: BlockPos, blockState: BlockState): SingleDeviceBlockEntity(BlockEntities.RELAY_ENTITY.get(), blockPos, blockState),
|
||||
GenericContainer, ComponentUser, MenuProvider {
|
||||
|
||||
companion object RelaySlots {
|
||||
val CARD = 0
|
||||
val CPU = 1
|
||||
val MEM = 2
|
||||
val STORAGE = 3
|
||||
|
||||
val SLOT_COUNT = 4
|
||||
}
|
||||
|
||||
val slots = NonNullList.withSize(SLOT_COUNT, ItemStack.EMPTY)!!
|
||||
|
||||
override fun getItems(): NonNullList<ItemStack> = slots
|
||||
|
||||
override fun stillValid(player: Player): Boolean = true
|
||||
|
||||
fun getUpgrade(slot: Int) = slots[slot].item as? RelayUpgrade
|
||||
|
||||
fun computeRelayInterval(): Int = getUpgrade(CPU)?.getRelayInterval(slots[CPU]) ?: 5
|
||||
fun computeRelayBufferSize(): Int = getUpgrade(MEM)?.getRelayBufferSize(slots[MEM]) ?: 1
|
||||
fun computeRelayQueueSize(): Int = getUpgrade(STORAGE)?.getRelayQueueSize(slots[STORAGE]) ?: 20
|
||||
fun getRelaySender(): DeviceNode? = getUpgrade(CARD)?.getComponentNode(slots[CARD])
|
||||
|
||||
fun computeRelayCapacity(): Int = computeRelayBufferSize() + computeRelayQueueSize()
|
||||
|
||||
val queue = mutableListOf<Networking.ClassicPacket>()
|
||||
var active = false
|
||||
var ticksUntilQueue = 0
|
||||
|
||||
override val deviceNode = object : DeviceNode() {
|
||||
override var reachability = Networking.Visibility.NONE
|
||||
override fun received(message: Networking.Message) {
|
||||
super.received(message)
|
||||
if(message.sender == this) return
|
||||
if(message is Networking.ClassicPacket && message.hopCount <= 5 && queue.size < computeRelayCapacity()) {
|
||||
queue.addLast(message)
|
||||
}
|
||||
}
|
||||
|
||||
override fun encodeScreenData(player: ServerPlayer, buf: FriendlyByteBuf) {
|
||||
super.encodeScreenData(player, buf)
|
||||
buf.writeVarInt(computeRelayInterval())
|
||||
buf.writeVarInt(computeRelayBufferSize())
|
||||
buf.writeVarInt(computeRelayQueueSize())
|
||||
buf.writeVarInt(queue.size)
|
||||
}
|
||||
|
||||
override fun writeFullStateCommit(buf: FriendlyByteBuf) {
|
||||
super.writeFullStateCommit(buf)
|
||||
buf.writeBoolean(active)
|
||||
}
|
||||
|
||||
override fun processCommit(buf: FriendlyByteBuf) {
|
||||
super.processCommit(buf)
|
||||
active = buf.readBoolean()
|
||||
}
|
||||
}
|
||||
|
||||
fun sendQueuedPacket() {
|
||||
if(queue.isEmpty()) return
|
||||
val pack = queue.removeFirst()
|
||||
|
||||
for(connection in deviceNode.connections) {
|
||||
// skip unwanted loopback
|
||||
if(connection !in pack.sender.getReachable()) continue
|
||||
val hopped = pack.hop(pack.sender)
|
||||
|
||||
if(connection is ConventionalNetworkDevice) {
|
||||
connection.sendClassicPacket(hopped)
|
||||
} else {
|
||||
Networking.emitMessage(connection, hopped)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun tickDevice(level: Level) {
|
||||
super.tickDevice(level)
|
||||
if(level !is ServerLevel) return
|
||||
ticksUntilQueue--
|
||||
if(ticksUntilQueue <= 0) {
|
||||
ticksUntilQueue = computeRelayInterval()
|
||||
val toSend = computeRelayBufferSize()
|
||||
for(i in 0..<toSend) {
|
||||
sendQueuedPacket()
|
||||
}
|
||||
}
|
||||
val cap = computeRelayCapacity()
|
||||
while(queue.size > cap) queue.removeLast()
|
||||
active = queue.isNotEmpty()
|
||||
}
|
||||
|
||||
override fun getMachineBlockPosition() = blockPos!!
|
||||
|
||||
override fun getMachineLevel() = level!!
|
||||
|
||||
override fun getMachineNode() = deviceNode
|
||||
|
||||
override fun getDisplayName() = Component.translatable("block.neocomputers.relay")!!
|
||||
|
||||
override fun createMenu(
|
||||
i: Int,
|
||||
inventory: Inventory,
|
||||
player: Player
|
||||
) = RelayMenu(i, inventory, this)
|
||||
|
||||
override fun loadAdditional(tag: CompoundTag, registries: HolderLookup.Provider) {
|
||||
super.loadAdditional(tag, registries)
|
||||
ContainerHelper.loadAllItems(tag, slots, registries)
|
||||
}
|
||||
|
||||
override fun saveAdditional(tag: CompoundTag, registries: HolderLookup.Provider) {
|
||||
super.saveAdditional(tag, registries)
|
||||
ContainerHelper.saveAllItems(tag, slots, registries)
|
||||
}
|
||||
}
|
||||
|
||||
class RelayBlock: DeviceBlock(Properties.of().sound(SoundType.METAL)) {
|
||||
override fun newBlockEntity(pos: BlockPos, state: BlockState) = RelayEntity(pos, state)
|
||||
|
||||
override fun useWithoutItem(
|
||||
state: BlockState,
|
||||
level: Level,
|
||||
pos: BlockPos,
|
||||
player: Player,
|
||||
hitResult: BlockHitResult
|
||||
): InteractionResult {
|
||||
if(!level.isClientSide) {
|
||||
val ent = level.getBlockEntity(pos, BlockEntities.RELAY_ENTITY.get()).get()
|
||||
// Open menu
|
||||
MenuRegistry.openMenu(player as ServerPlayer, ent)
|
||||
NodeSynchronizer.registerPlayerScreen(player, ent.deviceNode)
|
||||
}
|
||||
return InteractionResult.SUCCESS
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@ import org.neoflock.neocomputers.block.CapacitorEntity
|
||||
import org.neoflock.neocomputers.block.CapacitorEntityTier1
|
||||
import org.neoflock.neocomputers.block.CapacitorEntityTier2
|
||||
import org.neoflock.neocomputers.block.CapacitorEntityTier3
|
||||
import org.neoflock.neocomputers.block.RelayEntity
|
||||
import org.neoflock.neocomputers.network.PowerManager
|
||||
|
||||
// complete fucking bullshit btw
|
||||
@@ -87,6 +88,12 @@ object BlockEntities {
|
||||
)
|
||||
}
|
||||
|
||||
val RELAY_ENTITY: RegistrySupplier<BlockEntityType<RelayEntity>> = BLOCKENTITIES.register("relay") {
|
||||
BlockEntityType(
|
||||
::RelayEntity, setOf(Blocks.RELAY_BLOCK.get()), BullshitFix()
|
||||
)
|
||||
}
|
||||
|
||||
fun registerPowerBlocks() {
|
||||
PowerManager.registerPowerDevice(CAPACITOR_ENTITY.get())
|
||||
PowerManager.registerPowerDevice(CAPACITOR2_ENTITY.get())
|
||||
|
||||
@@ -11,6 +11,7 @@ import net.minecraft.network.FriendlyByteBuf
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.sounds.SoundSource
|
||||
import net.minecraft.world.Container
|
||||
import net.minecraft.world.ContainerHelper
|
||||
import net.minecraft.world.MenuProvider
|
||||
import net.minecraft.world.entity.player.Inventory
|
||||
@@ -289,4 +290,7 @@ class CaseBlockEntity(blockPos: BlockPos, blockState: BlockState): SingleDeviceB
|
||||
setRunning(false)
|
||||
super.setRemoved()
|
||||
}
|
||||
|
||||
override fun canPlaceItem(slot: Int, stack: ItemStack): Boolean = false
|
||||
override fun canTakeItem(target: Container, slot: Int, stack: ItemStack): Boolean = false
|
||||
}
|
||||
@@ -4,9 +4,7 @@ import net.minecraft.core.BlockPos
|
||||
import net.minecraft.core.Direction
|
||||
import net.minecraft.world.level.Level
|
||||
import net.minecraft.world.phys.Vec3
|
||||
import org.neoflock.neocomputers.item.ComponentItem
|
||||
import org.neoflock.neocomputers.network.DeviceNode
|
||||
import org.neoflock.neocomputers.network.Networking
|
||||
import java.time.Duration
|
||||
|
||||
abstract class MachineEvent {
|
||||
@@ -17,12 +15,16 @@ data class MachineRedstoneEvent(override val machine: MachineEntity, val side: D
|
||||
data class MachinePowerEvent(override val machine: MachineEntity, val nowRunning: Boolean): MachineEvent()
|
||||
data class MachineCrashEvent(override val machine: MachineEntity, val error: String): MachineEvent()
|
||||
|
||||
interface MachineEntity {
|
||||
interface ComponentUser {
|
||||
// Block position of machine, for wireless tech
|
||||
fun getMachineBlockPosition(): BlockPos
|
||||
fun getMachinePrecisePosition(): Vec3 = getMachineBlockPosition().center
|
||||
fun getMachineLevel(): Level
|
||||
|
||||
fun getMachineNode(): DeviceNode
|
||||
}
|
||||
|
||||
interface MachineEntity: ComponentUser {
|
||||
// Pattern can have dots (.), dashes (-) and spaces ( ).
|
||||
// Each character is duration long, and has a 50ms break.
|
||||
// For non-short ones, which are typically reserved only for hardware interactions,
|
||||
@@ -40,8 +42,6 @@ interface MachineEntity {
|
||||
fun crash(error: String): Boolean
|
||||
fun getLastError(): String?
|
||||
|
||||
fun getMachineNode(): DeviceNode
|
||||
|
||||
// Some metadata
|
||||
fun getMachineMemoryTotal(): Long
|
||||
fun getMachineMemoryUsed(): Long
|
||||
|
||||
@@ -11,7 +11,7 @@ import org.neoflock.neocomputers.network.DeviceNode
|
||||
import org.neoflock.neocomputers.network.PowerRole
|
||||
|
||||
class SolarGeneratorBlockEntity(blockPos: BlockPos, blockState: BlockState) : SingleDeviceBlockEntity(BlockEntities.SOLARGEN_ENTITY.get(), blockPos, blockState) {
|
||||
val energyPerTick: Long = 50
|
||||
val energyPerTick: Long = 10
|
||||
|
||||
override val deviceNode = object : DeviceNode() {
|
||||
override var powerRole: PowerRole = PowerRole.GENERATOR
|
||||
|
||||
@@ -12,19 +12,21 @@ import org.neoflock.neocomputers.NeoComputers
|
||||
import org.neoflock.neocomputers.gui.menu.ScreenMenu
|
||||
import org.neoflock.neocomputers.gui.screen.CaseScreen
|
||||
import org.neoflock.neocomputers.gui.screen.CombustionGeneratorScreen
|
||||
import org.neoflock.neocomputers.gui.screen.RelayScreen
|
||||
import org.neoflock.neocomputers.gui.screen.ScreenScreen
|
||||
|
||||
object Menus {
|
||||
val MENUS: DeferredRegister<MenuType<*>> = DeferredRegister.create(NeoComputers.MODID, Registries.MENU)
|
||||
|
||||
// val SCREEN_MENU: RegistrySupplier<MenuType<ScreenMenu>> = MENUS.register("screen_menu") { MenuType(::ScreenMenu, FeatureFlagSet.of()) }
|
||||
val SCREEN_MENU: RegistrySupplier<MenuType<ScreenMenu>> = MENUS.register("screen_menu") { MenuRegistry.ofExtended<ScreenMenu>(::ScreenMenu) }
|
||||
val COMBUSTGEN_MENU: RegistrySupplier<MenuType<CombustionGeneratorMenu>> = MENUS.register("combustgen_menu") { MenuType(::CombustionGeneratorMenu, FeatureFlagSet.of() ) }
|
||||
val CASE_MENU: RegistrySupplier<MenuType<CaseMenu>> = MENUS.register("case_menu") { MenuType(::CaseMenu, FeatureFlagSet.of() )}
|
||||
val RELAY_MENU: RegistrySupplier<MenuType<RelayMenu>> = MENUS.register("relay_menu") { MenuType(::RelayMenu, FeatureFlagSet.of() )}
|
||||
|
||||
fun registerScreens() {
|
||||
MenuScreens.register(Menus.COMBUSTGEN_MENU.get()) { m: CombustionGeneratorMenu, u, comp ->CombustionGeneratorScreen(m,u,comp)}
|
||||
MenuScreens.register(Menus.SCREEN_MENU.get(), ::ScreenScreen)
|
||||
MenuScreens.register(Menus.CASE_MENU.get(), ::CaseScreen)
|
||||
MenuScreens.register(Menus.RELAY_MENU.get(), ::RelayScreen)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
package org.neoflock.neocomputers.gui.menu
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem
|
||||
import net.minecraft.client.gui.GuiGraphics
|
||||
import net.minecraft.client.renderer.GameRenderer
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.world.Container
|
||||
import net.minecraft.world.SimpleContainer
|
||||
import net.minecraft.world.entity.player.Inventory
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import org.neoflock.neocomputers.NeoComputers
|
||||
import org.neoflock.neocomputers.block.RelayEntity
|
||||
import org.neoflock.neocomputers.gui.widget.ComponentRoles
|
||||
import org.neoflock.neocomputers.gui.widget.DynamicSlot
|
||||
import org.neoflock.neocomputers.item.ComponentItem
|
||||
import org.neoflock.neocomputers.item.RelayUpgrade
|
||||
import org.neoflock.neocomputers.utils.GenericContainerMenu
|
||||
|
||||
class RelaySlot(container: Container, slot: Int, x: Int, y: Int, val role: String, val relay: RelayEntity?) : DynamicSlot(container, slot, x, y) {
|
||||
override fun mayPlace(stack: ItemStack): Boolean {
|
||||
if(stack.isEmpty) return true
|
||||
val upgrade = stack.item as? RelayUpgrade ?: return false
|
||||
if(containerSlot == RelayEntity.CARD) {
|
||||
return upgrade.isRelayCompatibleCard(stack)
|
||||
}
|
||||
if(containerSlot == RelayEntity.CPU) {
|
||||
return upgrade.getRelayInterval(stack) != null
|
||||
}
|
||||
if(containerSlot == RelayEntity.MEM) {
|
||||
return upgrade.getRelayBufferSize(stack) != null
|
||||
}
|
||||
if(containerSlot == RelayEntity.STORAGE) {
|
||||
return upgrade.getRelayQueueSize(stack) != null
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override fun set(stack: ItemStack) {
|
||||
super.set(stack)
|
||||
val item = stack.item
|
||||
if(item is ComponentItem) {
|
||||
item.whenComponentPlaced(stack, relay, role)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onTake(player: Player, stack: ItemStack) {
|
||||
super.onTake(player, stack)
|
||||
val item = stack.item
|
||||
if(item is ComponentItem) {
|
||||
item.whenComponentTaken(stack, relay, role)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getMaxStackSize() = 1
|
||||
override fun getMaxStackSize(stack: ItemStack) = 1
|
||||
|
||||
override fun draw(graphics: GuiGraphics, relX: Int, relY: Int, mouseX: Int, mouseY: Int) {
|
||||
super.draw(graphics, relX, relY, mouseX, mouseY)
|
||||
if(!hasItem()) {
|
||||
RenderSystem.enableBlend()
|
||||
RenderSystem.setShaderTexture(0, ComponentRoles.getTextureFor(role))
|
||||
RenderSystem.setShader { GameRenderer.getPositionTexShader() }
|
||||
drawQuad(relX + x - 1, relY + y - 1, 18, 18, 0F, 0F, 15F, 15F)
|
||||
RenderSystem.disableBlend()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class RelayMenu : GenericContainerMenu {
|
||||
constructor(i: Int, inv: Inventory) : this(i, inv, SimpleContainer(RelayEntity.SLOT_COUNT))
|
||||
|
||||
constructor(i: Int, inv: Inventory, container: Container) : super(Menus.RELAY_MENU.get(), i, container) {
|
||||
val relay = container as? RelayEntity
|
||||
|
||||
val relayMenuWidth = 176
|
||||
val itemX = 152
|
||||
val itemRowDist = 16
|
||||
val itemSpacing = 20
|
||||
|
||||
this.addSlot(RelaySlot(container, RelayEntity.CARD, relayMenuWidth+4, itemRowDist, ComponentRoles.NETWORK, relay))
|
||||
|
||||
this.addSlot(RelaySlot(container, RelayEntity.CPU, itemX, itemRowDist, ComponentRoles.COMPUTE, relay))
|
||||
this.addSlot(RelaySlot(container, RelayEntity.MEM, itemX, itemRowDist+itemSpacing, ComponentRoles.MEMORY, relay))
|
||||
this.addSlot(RelaySlot(container, RelayEntity.STORAGE, itemX, itemRowDist+itemSpacing*2, ComponentRoles.STORAGE, relay))
|
||||
|
||||
this.addInventorySlots(inv, 8, 84)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package org.neoflock.neocomputers.gui.screen
|
||||
|
||||
import net.minecraft.ChatFormatting
|
||||
import net.minecraft.client.gui.GuiGraphics
|
||||
import net.minecraft.network.FriendlyByteBuf
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.network.chat.Style
|
||||
import net.minecraft.world.entity.player.Inventory
|
||||
import net.minecraft.world.item.DyeColor
|
||||
import org.neoflock.neocomputers.gui.menu.RelayMenu
|
||||
import org.neoflock.neocomputers.utils.GenericContainerScreen
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
|
||||
class RelayScreen(abstractContainerMenu: RelayMenu, inventory: Inventory, component: Component): GenericContainerScreen<RelayMenu>(abstractContainerMenu, inventory, component) {
|
||||
var interval: Int = 5
|
||||
var bufferSize: Int = 1
|
||||
var queueSize: Int = 20
|
||||
var inQueue: Int = 0
|
||||
|
||||
override fun shouldCenterTitle(): Boolean = false
|
||||
|
||||
override fun processScreenStatePacket(buf: FriendlyByteBuf) {
|
||||
super.processScreenStatePacket(buf)
|
||||
interval = buf.readVarInt()
|
||||
bufferSize = buf.readVarInt()
|
||||
queueSize = buf.readVarInt()
|
||||
inQueue = buf.readVarInt()
|
||||
}
|
||||
|
||||
override fun render(graphics: GuiGraphics, mouseX: Int, mouseY: Int, something: Float) {
|
||||
super.render(graphics, mouseX, mouseY, something)
|
||||
val textX = imageX + 12
|
||||
val dataX = imageX + 100
|
||||
val textSpacing = 20
|
||||
val textY = imageY + 20
|
||||
val clr = ChatFormatting.DARK_GRAY.color!!
|
||||
|
||||
graphics.drawString(this.font, "Cycle rate", textX, textY, clr, false)
|
||||
graphics.drawString(this.font, "Packets / cycle", textX, textY + textSpacing, clr, false)
|
||||
graphics.drawString(this.font, "Queue Size", textX, textY + textSpacing*2, clr, false)
|
||||
|
||||
val hz = if(interval == 0) 20 else 20 / interval
|
||||
val buffered = min(inQueue, bufferSize)
|
||||
val queued = max(inQueue - bufferSize, 0)
|
||||
|
||||
graphics.drawString(this.font, "$hz Hz", dataX, textY, clr, false)
|
||||
graphics.drawString(this.font, "$buffered / $bufferSize", dataX, textY + textSpacing, clr, false)
|
||||
graphics.drawString(this.font, "$queued / $queueSize", dataX, textY + textSpacing * 2, clr, false)
|
||||
}
|
||||
}
|
||||
@@ -6,11 +6,9 @@ import net.minecraft.client.renderer.GameRenderer
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.world.Container
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.item.Item
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.level.ItemLike
|
||||
import org.neoflock.neocomputers.NeoComputers
|
||||
import org.neoflock.neocomputers.entity.MachineEntity
|
||||
import org.neoflock.neocomputers.entity.ComponentUser
|
||||
import org.neoflock.neocomputers.item.ComponentItem
|
||||
|
||||
// Sort of a mis-nomer, does not need to be associated with components specifically
|
||||
@@ -85,7 +83,7 @@ data class ComponentSlotRequirement(val tier: Int, val role: String) {
|
||||
|
||||
// Tier 0 allows ALL tiers, making it completely untiered.
|
||||
// Role determines what the role is.
|
||||
class ComponentSlot(container: Container, slot: Int, x: Int, y: Int, val machine: MachineEntity?, val requirement: ComponentSlotRequirement): DynamicSlot(container, slot, x, y) {
|
||||
class ComponentSlot(container: Container, slot: Int, x: Int, y: Int, val machine: ComponentUser?, val requirement: ComponentSlotRequirement): DynamicSlot(container, slot, x, y) {
|
||||
override fun draw(graphics: GuiGraphics, relX: Int, relY: Int, mouseX: Int, mouseY: Int) {
|
||||
super.draw(graphics, relX, relY, mouseX, mouseY)
|
||||
if(!hasItem()) {
|
||||
|
||||
@@ -2,9 +2,8 @@ package org.neoflock.neocomputers.item
|
||||
|
||||
import net.minecraft.world.item.Item
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import org.neoflock.neocomputers.entity.MachineEntity
|
||||
import org.neoflock.neocomputers.entity.ComponentUser
|
||||
import org.neoflock.neocomputers.gui.widget.ComponentRoles
|
||||
import org.neoflock.neocomputers.network.Networking
|
||||
|
||||
open class CBUSItem(val tier: Int, val maxComponents: Int): Item(Item.Properties()), ComponentItem {
|
||||
override fun getComponentRoles(itemStack: ItemStack) = setOf(ComponentRoles.BUS)
|
||||
@@ -13,7 +12,7 @@ open class CBUSItem(val tier: Int, val maxComponents: Int): Item(Item.Properties
|
||||
|
||||
override fun getComponentCapacity(itemStack: ItemStack) = maxComponents
|
||||
|
||||
override fun toComponentNode(itemStack: ItemStack, machine: MachineEntity?) = null
|
||||
override fun toComponentNode(itemStack: ItemStack, machine: ComponentUser?) = null
|
||||
}
|
||||
class CBUS0: CBUSItem(1, 8)
|
||||
class CBUS1: CBUSItem(2, 12)
|
||||
|
||||
@@ -2,11 +2,10 @@ package org.neoflock.neocomputers.item
|
||||
|
||||
import net.minecraft.world.item.Item
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import org.neoflock.neocomputers.entity.MachineEntity
|
||||
import org.neoflock.neocomputers.entity.ComponentUser
|
||||
import org.neoflock.neocomputers.gui.widget.ComponentRoles
|
||||
import org.neoflock.neocomputers.network.Networking
|
||||
|
||||
open class CPUItem(val tier: Int, val maxComponents: Int): Item(Item.Properties()), ComponentItem {
|
||||
open class CPUItem(val tier: Int, val maxComponents: Int): Item(Item.Properties()), RelayUpgrade {
|
||||
override fun getComponentRoles(itemStack: ItemStack): Set<String> = setOf(ComponentRoles.COMPUTE)
|
||||
|
||||
override fun getComponentTier(itemStack: ItemStack): Int = tier
|
||||
@@ -15,7 +14,9 @@ open class CPUItem(val tier: Int, val maxComponents: Int): Item(Item.Properties(
|
||||
|
||||
override fun getArchitecturesProvided(itemStack: ItemStack): Set<String> = setOf("Lua 5.3")
|
||||
|
||||
override fun toComponentNode(itemStack: ItemStack, machine: MachineEntity?) = null
|
||||
override fun toComponentNode(itemStack: ItemStack, machine: ComponentUser?) = null
|
||||
|
||||
override fun getRelayInterval(itemStack: ItemStack) = 4 / tier
|
||||
}
|
||||
|
||||
class CPU0: CPUItem(1, 8)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.neoflock.neocomputers.item
|
||||
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import org.neoflock.neocomputers.entity.ComponentUser
|
||||
import org.neoflock.neocomputers.entity.MachineEntity
|
||||
import org.neoflock.neocomputers.entity.MachineEvent
|
||||
import org.neoflock.neocomputers.network.DeviceNode
|
||||
@@ -18,7 +19,7 @@ interface ComponentItem {
|
||||
fun getArchitecturesProvided(itemStack: ItemStack): Set<String> = setOf()
|
||||
|
||||
// Component placed, node must now exist
|
||||
fun whenComponentPlaced(itemStack: ItemStack, machine: MachineEntity?, newRole: String) {
|
||||
fun whenComponentPlaced(itemStack: ItemStack, machine: ComponentUser?, newRole: String) {
|
||||
val oldNode = getComponentNode(itemStack)
|
||||
if(oldNode != null) Networking.removeNode(oldNode) // did a mod forget to call whenComponentTaken?
|
||||
val node = toComponentNode(itemStack, machine) ?: return
|
||||
@@ -27,14 +28,14 @@ interface ComponentItem {
|
||||
}
|
||||
|
||||
// Component taken, and thus removed
|
||||
fun whenComponentTaken(itemStack: ItemStack, machine: MachineEntity?, previousRole: String) {
|
||||
fun whenComponentTaken(itemStack: ItemStack, machine: ComponentUser?, previousRole: String) {
|
||||
val node = getComponentNode(itemStack) ?: return
|
||||
// removing disconnects
|
||||
Networking.removeNode(node)
|
||||
}
|
||||
|
||||
// To node, if applicable. Meant to create the node, but not add it, as it will use the itemStack's address to find it again
|
||||
fun toComponentNode(itemStack: ItemStack, machine: MachineEntity?): DeviceNode?
|
||||
fun toComponentNode(itemStack: ItemStack, machine: ComponentUser?): DeviceNode?
|
||||
|
||||
// Gets the node associated to an item, if it exists
|
||||
fun getComponentNode(itemStack: ItemStack): DeviceNode? {
|
||||
@@ -58,4 +59,5 @@ interface RelayUpgrade: ComponentItem {
|
||||
fun getRelayInterval(itemStack: ItemStack): Int? = null
|
||||
fun getRelayBufferSize(itemStack: ItemStack): Int? = null
|
||||
fun getRelayQueueSize(itemStack: ItemStack): Int? = null
|
||||
fun isRelayCompatibleCard(itemStack: ItemStack): Boolean = false
|
||||
}
|
||||
@@ -4,9 +4,8 @@ import net.minecraft.network.chat.Component
|
||||
import net.minecraft.world.item.Item
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.item.TooltipFlag
|
||||
import org.neoflock.neocomputers.entity.MachineEntity
|
||||
import org.neoflock.neocomputers.entity.ComponentUser
|
||||
import org.neoflock.neocomputers.gui.widget.ComponentRoles
|
||||
import org.neoflock.neocomputers.network.Networking
|
||||
import org.neoflock.neocomputers.utils.Formatting
|
||||
|
||||
// Note: We'll prob want to replace them with NN component configs later on
|
||||
@@ -16,13 +15,13 @@ open class DataCard(val tier: Int, val limit: Long): Item(Properties()), Compone
|
||||
|
||||
override fun getComponentTier(itemStack: ItemStack): Int = tier
|
||||
|
||||
override fun whenComponentPlaced(itemStack: ItemStack, machine: MachineEntity?, newRole: String) {
|
||||
override fun whenComponentPlaced(itemStack: ItemStack, machine: ComponentUser?, newRole: String) {
|
||||
if(machine != null) ensureHasAddress(itemStack)
|
||||
super.whenComponentPlaced(itemStack, machine, newRole)
|
||||
}
|
||||
|
||||
// TODO: Modem Component
|
||||
override fun toComponentNode(itemStack: ItemStack, machine: MachineEntity?) = null
|
||||
override fun toComponentNode(itemStack: ItemStack, machine: ComponentUser?) = null
|
||||
|
||||
override fun appendHoverText(
|
||||
itemStack: ItemStack,
|
||||
|
||||
@@ -4,9 +4,8 @@ import net.minecraft.network.chat.Component
|
||||
import net.minecraft.world.item.Item
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.item.TooltipFlag
|
||||
import org.neoflock.neocomputers.entity.MachineEntity
|
||||
import org.neoflock.neocomputers.entity.ComponentUser
|
||||
import org.neoflock.neocomputers.gui.widget.ComponentRoles
|
||||
import org.neoflock.neocomputers.network.Networking
|
||||
import org.neoflock.neocomputers.utils.Formatting
|
||||
import java.nio.ByteBuffer
|
||||
|
||||
@@ -27,12 +26,12 @@ open class EEPROMItem(val tier: Int, val codeCapacity: Int, val dataCapacity: In
|
||||
|
||||
override fun getComponentCapacity(itemStack: ItemStack): Int = 0
|
||||
|
||||
override fun whenComponentPlaced(itemStack: ItemStack, machine: MachineEntity?, newRole: String) {
|
||||
override fun whenComponentPlaced(itemStack: ItemStack, machine: ComponentUser?, newRole: String) {
|
||||
if(machine != null) ensureHasAddress(itemStack)
|
||||
super.whenComponentPlaced(itemStack, machine, newRole)
|
||||
}
|
||||
|
||||
override fun toComponentNode(itemStack: ItemStack, machine: MachineEntity?) = null
|
||||
override fun toComponentNode(itemStack: ItemStack, machine: ComponentUser?) = null
|
||||
|
||||
override fun appendHoverText(
|
||||
itemStack: ItemStack,
|
||||
|
||||
@@ -4,9 +4,8 @@ import net.minecraft.network.chat.Component
|
||||
import net.minecraft.world.item.Item
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.item.TooltipFlag
|
||||
import org.neoflock.neocomputers.entity.MachineEntity
|
||||
import org.neoflock.neocomputers.entity.ComponentUser
|
||||
import org.neoflock.neocomputers.gui.widget.ComponentRoles
|
||||
import org.neoflock.neocomputers.network.Networking
|
||||
|
||||
// Note: We'll prob want to replace them with NN component configs later on
|
||||
|
||||
@@ -15,13 +14,13 @@ open class GPUCard(val tier: Int, val vram: Long): Item(Properties()), Component
|
||||
|
||||
override fun getComponentTier(itemStack: ItemStack): Int = tier
|
||||
|
||||
override fun whenComponentPlaced(itemStack: ItemStack, machine: MachineEntity?, newRole: String) {
|
||||
override fun whenComponentPlaced(itemStack: ItemStack, machine: ComponentUser?, newRole: String) {
|
||||
if(machine != null) ensureHasAddress(itemStack)
|
||||
super.whenComponentPlaced(itemStack, machine, newRole)
|
||||
}
|
||||
|
||||
// TODO: GPU Component
|
||||
override fun toComponentNode(itemStack: ItemStack, machine: MachineEntity?) = null
|
||||
override fun toComponentNode(itemStack: ItemStack, machine: ComponentUser?) = null
|
||||
|
||||
override fun appendHoverText(
|
||||
itemStack: ItemStack,
|
||||
|
||||
@@ -4,17 +4,15 @@ import net.minecraft.network.chat.Component
|
||||
import net.minecraft.world.item.Item
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.item.TooltipFlag
|
||||
import org.neoflock.neocomputers.entity.MachineEntity
|
||||
import org.neoflock.neocomputers.entity.ComponentUser
|
||||
import org.neoflock.neocomputers.gui.widget.ComponentRoles
|
||||
import org.neoflock.neocomputers.network.Networking
|
||||
import org.neoflock.neocomputers.utils.Formatting
|
||||
import java.util.UUID
|
||||
|
||||
fun getDiskProperties(): Item.Properties = Item.Properties()
|
||||
.component(DataComponents.LABEL, "")
|
||||
.component(DataComponents.READONLY, false)
|
||||
|
||||
open class HardDiskItem(val tier: Int, val capacity: Long): Item(getDiskProperties()), ComponentItem {
|
||||
open class HardDiskItem(val tier: Int, val capacity: Long, val relayQueueSize: Int): Item(getDiskProperties()), RelayUpgrade {
|
||||
override fun getComponentRoles(itemStack: ItemStack): Set<String> = setOf(ComponentRoles.STORAGE)
|
||||
|
||||
override fun getComponentTier(itemStack: ItemStack): Int = tier
|
||||
@@ -23,12 +21,12 @@ open class HardDiskItem(val tier: Int, val capacity: Long): Item(getDiskProperti
|
||||
|
||||
override fun getComponentCapacity(itemStack: ItemStack): Int = 0
|
||||
|
||||
override fun whenComponentPlaced(itemStack: ItemStack, machine: MachineEntity?, newRole: String) {
|
||||
override fun whenComponentPlaced(itemStack: ItemStack, machine: ComponentUser?, newRole: String) {
|
||||
if(machine != null) ensureHasAddress(itemStack)
|
||||
super.whenComponentPlaced(itemStack, machine, newRole)
|
||||
}
|
||||
|
||||
override fun toComponentNode(itemStack: ItemStack, machine: MachineEntity?) = null
|
||||
override fun toComponentNode(itemStack: ItemStack, machine: ComponentUser?) = null
|
||||
|
||||
override fun appendHoverText(
|
||||
itemStack: ItemStack,
|
||||
@@ -56,8 +54,10 @@ open class HardDiskItem(val tier: Int, val capacity: Long): Item(getDiskProperti
|
||||
}
|
||||
return super.getName(itemStack)
|
||||
}
|
||||
|
||||
override fun getRelayQueueSize(itemStack: ItemStack) = relayQueueSize
|
||||
}
|
||||
|
||||
class HardDisk0: HardDiskItem(1, 1 shl 20)
|
||||
class HardDisk1: HardDiskItem(2, 2 shl 20)
|
||||
class HardDisk2: HardDiskItem(3, 4 shl 20)
|
||||
class HardDisk0: HardDiskItem(1, 1 shl 20, 30)
|
||||
class HardDisk1: HardDiskItem(2, 2 shl 20, 40)
|
||||
class HardDisk2: HardDiskItem(3, 4 shl 20, 50)
|
||||
@@ -4,23 +4,21 @@ import net.minecraft.network.chat.Component
|
||||
import net.minecraft.world.item.Item
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.item.TooltipFlag
|
||||
import org.neoflock.neocomputers.entity.MachineEntity
|
||||
import org.neoflock.neocomputers.entity.ComponentUser
|
||||
import org.neoflock.neocomputers.gui.widget.ComponentRoles
|
||||
import org.neoflock.neocomputers.network.Networking
|
||||
import org.neoflock.neocomputers.utils.Formatting
|
||||
|
||||
class InternetCard: Item(Item.Properties()), ComponentItem {
|
||||
override fun getComponentRoles(itemStack: ItemStack): Set<String> = setOf(ComponentRoles.CARD, ComponentRoles.INET)
|
||||
|
||||
override fun getComponentTier(itemStack: ItemStack): Int = 1
|
||||
|
||||
override fun whenComponentPlaced(itemStack: ItemStack, machine: MachineEntity?, newRole: String) {
|
||||
override fun whenComponentPlaced(itemStack: ItemStack, machine: ComponentUser?, newRole: String) {
|
||||
if(machine != null) ensureHasAddress(itemStack)
|
||||
super.whenComponentPlaced(itemStack, machine, newRole)
|
||||
}
|
||||
|
||||
// TODO: Internet Component
|
||||
override fun toComponentNode(itemStack: ItemStack, machine: MachineEntity?) = null
|
||||
override fun toComponentNode(itemStack: ItemStack, machine: ComponentUser?) = null
|
||||
|
||||
override fun appendHoverText(
|
||||
itemStack: ItemStack,
|
||||
|
||||
@@ -4,13 +4,11 @@ import net.minecraft.network.chat.Component
|
||||
import net.minecraft.world.item.Item
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.item.TooltipFlag
|
||||
import org.neoflock.neocomputers.entity.MachineEntity
|
||||
import org.neoflock.neocomputers.entity.ComponentUser
|
||||
import org.neoflock.neocomputers.gui.widget.ComponentRoles
|
||||
import org.neoflock.neocomputers.network.DeviceNode
|
||||
import org.neoflock.neocomputers.network.Networking
|
||||
import org.neoflock.neocomputers.utils.Formatting
|
||||
|
||||
open class MemoryItem(val tier: Int, val capacity: Int): Item(Item.Properties().`arch$tab`(Tabs.TAB)), ComponentItem {
|
||||
open class MemoryItem(val tier: Int, val capacity: Int, val relayBuf: Int): Item(Item.Properties().`arch$tab`(Tabs.TAB)), RelayUpgrade {
|
||||
override fun getComponentRoles(itemStack: ItemStack) = setOf(ComponentRoles.MEMORY)
|
||||
|
||||
override fun getComponentTier(itemStack: ItemStack): Int = tier
|
||||
@@ -20,7 +18,7 @@ open class MemoryItem(val tier: Int, val capacity: Int): Item(Item.Properties().
|
||||
override fun getComponentCapacity(itemStack: ItemStack): Int = 0
|
||||
|
||||
// no node for memory
|
||||
override fun toComponentNode(itemStack: ItemStack, machine: MachineEntity?) = null
|
||||
override fun toComponentNode(itemStack: ItemStack, machine: ComponentUser?) = null
|
||||
|
||||
override fun appendHoverText(
|
||||
itemStack: ItemStack,
|
||||
@@ -33,11 +31,13 @@ open class MemoryItem(val tier: Int, val capacity: Int): Item(Item.Properties().
|
||||
}
|
||||
super.appendHoverText(itemStack, tooltipContext, list, tooltipFlag)
|
||||
}
|
||||
|
||||
override fun getRelayBufferSize(itemStack: ItemStack) = relayBuf
|
||||
}
|
||||
|
||||
class MemoryTier1(): MemoryItem(1, 192 shl 10)
|
||||
class MemoryTier1_5(): MemoryItem(1, 256 shl 10)
|
||||
class MemoryTier2(): MemoryItem(2, 384 shl 10)
|
||||
class MemoryTier2_5(): MemoryItem(2, 512 shl 10)
|
||||
class MemoryTier3(): MemoryItem(3, 768 shl 10)
|
||||
class MemoryTier3_5(): MemoryItem(3, 1 shl 20)
|
||||
class MemoryTier1(): MemoryItem(1, 192 shl 10, 2)
|
||||
class MemoryTier1_5(): MemoryItem(1, 256 shl 10, 3)
|
||||
class MemoryTier2(): MemoryItem(2, 384 shl 10, 4)
|
||||
class MemoryTier2_5(): MemoryItem(2, 512 shl 10, 5)
|
||||
class MemoryTier3(): MemoryItem(3, 768 shl 10, 6)
|
||||
class MemoryTier3_5(): MemoryItem(3, 1 shl 20, 7)
|
||||
@@ -4,22 +4,21 @@ import net.minecraft.network.chat.Component
|
||||
import net.minecraft.world.item.Item
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.item.TooltipFlag
|
||||
import org.neoflock.neocomputers.entity.MachineEntity
|
||||
import org.neoflock.neocomputers.entity.ComponentUser
|
||||
import org.neoflock.neocomputers.gui.widget.ComponentRoles
|
||||
import org.neoflock.neocomputers.network.Networking
|
||||
|
||||
open class NetworkCard(val tier: Int, val maxRange: Int, val isWired: Boolean): Item(Properties()), ComponentItem {
|
||||
override fun getComponentRoles(itemStack: ItemStack): Set<String> = setOf(ComponentRoles.CARD, ComponentRoles.NETWORK)
|
||||
|
||||
override fun getComponentTier(itemStack: ItemStack): Int = tier
|
||||
|
||||
override fun whenComponentPlaced(itemStack: ItemStack, machine: MachineEntity?, newRole: String) {
|
||||
override fun whenComponentPlaced(itemStack: ItemStack, machine: ComponentUser?, newRole: String) {
|
||||
if(machine != null) ensureHasAddress(itemStack)
|
||||
super.whenComponentPlaced(itemStack, machine, newRole)
|
||||
}
|
||||
|
||||
// TODO: Modem Component
|
||||
override fun toComponentNode(itemStack: ItemStack, machine: MachineEntity?) = null
|
||||
override fun toComponentNode(itemStack: ItemStack, machine: ComponentUser?) = null
|
||||
|
||||
override fun appendHoverText(
|
||||
itemStack: ItemStack,
|
||||
|
||||
@@ -4,9 +4,8 @@ import net.minecraft.network.chat.Component
|
||||
import net.minecraft.world.item.Item
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.item.TooltipFlag
|
||||
import org.neoflock.neocomputers.entity.MachineEntity
|
||||
import org.neoflock.neocomputers.entity.ComponentUser
|
||||
import org.neoflock.neocomputers.gui.widget.ComponentRoles
|
||||
import org.neoflock.neocomputers.network.Networking
|
||||
|
||||
// Note: We'll prob want to replace them with NN component configs later on
|
||||
|
||||
@@ -15,13 +14,13 @@ open class RedstoneCard(val tier: Int): Item(Properties()), ComponentItem {
|
||||
|
||||
override fun getComponentTier(itemStack: ItemStack): Int = tier
|
||||
|
||||
override fun whenComponentPlaced(itemStack: ItemStack, machine: MachineEntity?, newRole: String) {
|
||||
override fun whenComponentPlaced(itemStack: ItemStack, machine: ComponentUser?, newRole: String) {
|
||||
if(machine != null) ensureHasAddress(itemStack)
|
||||
super.whenComponentPlaced(itemStack, machine, newRole)
|
||||
}
|
||||
|
||||
// TODO: Redstone Component
|
||||
override fun toComponentNode(itemStack: ItemStack, machine: MachineEntity?) = null
|
||||
override fun toComponentNode(itemStack: ItemStack, machine: ComponentUser?) = null
|
||||
|
||||
override fun appendHoverText(
|
||||
itemStack: ItemStack,
|
||||
|
||||
@@ -4,9 +4,8 @@ import net.minecraft.network.chat.Component
|
||||
import net.minecraft.world.item.Item
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.item.TooltipFlag
|
||||
import org.neoflock.neocomputers.entity.MachineEntity
|
||||
import org.neoflock.neocomputers.entity.ComponentUser
|
||||
import org.neoflock.neocomputers.gui.widget.ComponentRoles
|
||||
import org.neoflock.neocomputers.network.Networking
|
||||
|
||||
class TunnelCard: Item(Properties().component(DataComponents.TUNNEL_CHANNEL, "creative")), ComponentItem {
|
||||
// yes, we're counting TUNNEL as a conventional networking card
|
||||
@@ -14,13 +13,13 @@ class TunnelCard: Item(Properties().component(DataComponents.TUNNEL_CHANNEL, "cr
|
||||
|
||||
override fun getComponentTier(itemStack: ItemStack): Int = 3
|
||||
|
||||
override fun whenComponentPlaced(itemStack: ItemStack, machine: MachineEntity?, newRole: String) {
|
||||
override fun whenComponentPlaced(itemStack: ItemStack, machine: ComponentUser?, newRole: String) {
|
||||
if(machine != null) ensureHasAddress(itemStack)
|
||||
super.whenComponentPlaced(itemStack, machine, newRole)
|
||||
}
|
||||
|
||||
// TODO: Tunnel Component
|
||||
override fun toComponentNode(itemStack: ItemStack, machine: MachineEntity?) = null
|
||||
override fun toComponentNode(itemStack: ItemStack, machine: ComponentUser?) = null
|
||||
|
||||
override fun appendHoverText(
|
||||
itemStack: ItemStack,
|
||||
|
||||
@@ -37,7 +37,7 @@ object Networking {
|
||||
abstract class Message(val sender: DeviceNode)
|
||||
|
||||
class ClassicPacket(sender: DeviceNode, val src: String, val dst: String, val port: Int, val data: List<Any>, val hopCount: Int) : Message(sender) {
|
||||
fun hop() = ClassicPacket(sender, src, dst, port, data, hopCount + 1);
|
||||
fun hop(sender: DeviceNode) = ClassicPacket(sender, src, dst, port, data, hopCount + 1);
|
||||
}
|
||||
|
||||
// for plugins and shi
|
||||
|
||||
Reference in New Issue
Block a user