Compare commits

...

7 Commits

Author SHA1 Message Date
adc29bff0c Correção do README 2025-12-11 19:22:09 -03:00
b162540450 Correção de bugs: - Corrigido: Duplicação ao mover itens além do disponível
- Corrigido: Itens renomeados perdendo nome
- Corrigido: Shulker boxes mesclando incorretamente e duplicando
2025-12-11 19:18:40 -03:00
ac26b22379 Correção de bugs: - Corrigido: Duplicação ao mover itens além do disponível
- Corrigido: Itens renomeados perdendo nome
- Corrigido: Shulker boxes mesclando incorretamente
2025-12-11 19:04:38 -03:00
4e549d8d7d dnv 2025-11-03 23:47:58 -03:00
259b173acb sla só quis trocar o icone 2025-11-03 23:46:49 -03:00
2f3390eaaa Merge branch 'main' of https://git.morpheusnox.shop/morpheus/backpack-infinita 2025-11-03 23:43:51 -03:00
238ba6a86c README adicionado(sim é só isso) 2025-11-03 23:42:45 -03:00
16 changed files with 216 additions and 23 deletions

70
README.md Normal file
View File

@@ -0,0 +1,70 @@
# Backpack Infinita
Plugin para Minecraft que adiciona uma mochila infinita ao servidor, permitindo armazenar itens ilimitados com paginação e controle preciso de quantidades.
## Funcionalidades
- **Mochila Infinita**: Armazenamento ilimitado com paginação (45 itens por página)
- **Comando**: `/backpack` ou `/bp` para abrir a mochila
- **Controle de Quantidades**:
- Clique esquerdo: Move 1 item para o cursor (permite escolher onde colocar)
- Clique direito no inventário: Coloca 1 item do cursor no slot
- Shift + clique esquerdo: Move o stack todo diretamente
- **Suporte a Itens Renomeados**: Preserva nomes customizados
- **Shulker Boxes**: Tratamento especial - não mesclam para evitar duplicação de conteúdo
- **Limites de Segurança**: Máximo 1000 itens por mochila, validação contra itens inválidos
- **Persistência**: Dados salvos em SQLite, sobrevive reinícios
## Instalação
1. Baixe o JAR mais recente do plugin
2. Coloque o arquivo no diretório `plugins` do seu servidor Minecraft
3. Reinicie o servidor ou use `/reload`
4. Configure permissões se necessário
## Como Usar
1. Digite `/backpack` no chat para abrir sua mochila
2. **Para tirar itens da mochila**:
- Clique esquerdo: Pega 1 item
- Shift + clique esquerdo: Move stack todo diretamente pro inventário
3. **Para mover itens para a mochila**:
- Shift + clique esquerdo no item: Move diretamente para a mochila
4. **Shulker Boxes**: Sempre ficam separadas na mochila para preservar conteúdo
## Permissões
- `backpack.use`: Permite usar o comando /backpack (padrão: todos os jogadores)
## Desenvolvimento
### Pré-requisitos
- Java 21
- Maven
### Compilação
```bash
mvn clean package
```
O JAR será gerado em `target/backpack-infinita-1.1.jar`
### Estrutura do Projeto
- `src/main/java/`: Código fonte
- `src/main/resources/`: Configurações (plugin.yml)
- `pom.xml`: Dependências Maven
## Bugs Conhecidos e Fixes
- Corrigido: Duplicação ao mover itens além do disponível
- Corrigido: Itens renomeados perdendo nome
- Corrigido: Shulker boxes mesclando incorretamente
- Corrigido: Problemas com sistema de cursor
## Suporte
Para bugs ou sugestões, abra uma issue no repositório.
## Licença
Este projeto está sob a licença GNU Lesser General Public License v3.0. Veja LICENSE para detalhes.

View File

@@ -117,9 +117,37 @@ public class Backpack {
}
}
private boolean isSimilarIgnoringDisplayNameAndLore(ItemStack item1, ItemStack item2) {
if (item1.getType() != item2.getType()) return false;
if (item1.getDurability() != item2.getDurability()) return false;
if (!item1.getEnchantments().equals(item2.getEnchantments())) return false;
// Ignora display name e lore para mesclar itens renomeados ou com lore customizada
ItemMeta meta1 = item1.getItemMeta();
ItemMeta meta2 = item2.getItemMeta();
if (meta1 != null && meta2 != null) {
// Compara apenas enchants e outros, ignorando display name e lore
return meta1.getEnchants().equals(meta2.getEnchants()) &&
(meta1.getAttributeModifiers() == null ? meta2.getAttributeModifiers() == null : meta1.getAttributeModifiers().equals(meta2.getAttributeModifiers()));
}
return meta1 == null && meta2 == null;
}
public void addItem(ItemStack item) {
// Validação: rejeita itens inválidos ou ar
if (item == null || item.getType().isAir() || !item.getType().isItem()) {
return; // Ignora itens inválidos
}
// Limite total de itens (ex.: 1000 para evitar abuso)
if (internalContents.size() >= 1000) {
return; // Não adiciona se exceder limite
}
// Para shulker boxes, não mesclar para evitar problemas com conteúdo
if (item.getType().name().contains("SHULKER_BOX")) {
internalContents.add(item.clone());
return;
}
for (ItemStack existingItem : internalContents) {
if (existingItem.isSimilar(item)) {
if (isSimilarIgnoringDisplayNameAndLore(existingItem, item)) {
existingItem.setAmount(existingItem.getAmount() + item.getAmount());
return;
}
@@ -131,7 +159,7 @@ public class Backpack {
Iterator<ItemStack> iterator = internalContents.iterator();
while (iterator.hasNext()) {
ItemStack existingItem = iterator.next();
if (existingItem.isSimilar(itemToRemove)) {
if (isSimilarIgnoringDisplayNameAndLore(existingItem, itemToRemove)) {
if (existingItem.getAmount() <= itemToRemove.getAmount()) {
iterator.remove();
} else {

View File

@@ -26,6 +26,11 @@ public class BackpackCommand implements CommandExecutor {
}
Player player = (Player) sender;
if (!player.hasPermission("backpack.use")) {
player.sendMessage("Você não tem permissão para usar este comando.");
return true;
}
Backpack backpack = plugin.getPlayerBackpack(player);
backpack.open();

View File

@@ -33,6 +33,11 @@ public final class BackpackInfinita extends JavaPlugin {
for (Map.Entry<UUID, Backpack> entry : playerBackpacks.entrySet()) {
savePlayerBackpack(entry.getKey(), entry.getValue());
}
// Fecha a conexão do banco de dados
if (database != null) {
database.closeConnection();
}
getLogger().info("Backpack Infinita desabilitado com sucesso.");
}
public Database getDatabase() {
@@ -51,8 +56,12 @@ public final class BackpackInfinita extends JavaPlugin {
ResultSet resultSet = statement.executeQuery();
if (resultSet.next()) {
backpack.fromBase64(resultSet.getString("items"));
getLogger().fine("Backpack carregada do DB para jogador: " + playerUUID);
} else {
getLogger().fine("Nova backpack criada para jogador: " + playerUUID);
}
} catch (SQLException | IOException e) {
getLogger().severe("Erro ao carregar backpack para " + playerUUID + ": " + e.getMessage());
e.printStackTrace();
}
playerBackpacks.put(playerUUID, backpack);
@@ -64,7 +73,9 @@ public final class BackpackInfinita extends JavaPlugin {
statement.setString(1, playerUUID.toString());
statement.setString(2, backpack.toBase64());
statement.executeUpdate();
getLogger().fine("Backpack salva para jogador: " + playerUUID);
} catch (SQLException e) {
getLogger().severe("Erro ao salvar backpack para " + playerUUID + ": " + e.getMessage());
e.printStackTrace();
}
}

View File

@@ -78,34 +78,93 @@ public class BackpackListener implements Listener {
lore.removeIf(line -> line.startsWith("§7Quantidade:"));
meta.setLore(lore);
}
if (meta.hasDisplayName()) {
meta.setDisplayName(null);
}
// Preserva o display name customizado
itemToTransfer.setItemMeta(meta);
}
int amountToTransfer = itemToTransfer.getMaxStackSize();
int amountToTransfer = 1; // Clique normal: 1 item
if (event.isShiftClick()) {
amountToTransfer = trueItem.getAmount();
amountToTransfer = trueItem.getAmount(); // Shift-click: stack todo
}
amountToTransfer = Math.min(amountToTransfer, trueItem.getAmount());
itemToTransfer.setAmount(amountToTransfer);
// Tenta adicionar ao inventário do jogador
int remaining = player.getInventory().addItem(itemToTransfer).values().stream()
.mapToInt(ItemStack::getAmount).sum();
if (event.isShiftClick()) {
// Shift-click: move diretamente para o inventário
int remaining = player.getInventory().addItem(itemToTransfer).values().stream()
.mapToInt(ItemStack::getAmount).sum();
if (remaining < amountToTransfer) {
// Alguns itens foram transferidos
ItemStack removedFromBackpack = trueItem.clone();
removedFromBackpack.setAmount(amountToTransfer - remaining);
backpack.removeItem(removedFromBackpack);
if (remaining < amountToTransfer) {
// Alguns itens foram transferidos
if (trueItem.getType().name().contains("SHULKER_BOX")) {
// Para shulker boxes, remover por index para evitar remover a errada
backpack.getInternalContents().remove(internalIndex);
} else {
ItemStack removedFromBackpack = trueItem.clone();
removedFromBackpack.setAmount(amountToTransfer - remaining);
backpack.removeItem(removedFromBackpack);
}
}
} else {
// Clique normal: move para o cursor
if (event.getCursor() == null || event.getCursor().getType().isAir()) {
event.getWhoClicked().setItemOnCursor(itemToTransfer);
// Remove da mochila
if (trueItem.getType().name().contains("SHULKER_BOX")) {
backpack.getInternalContents().remove(internalIndex);
} else {
ItemStack removedFromBackpack = trueItem.clone();
removedFromBackpack.setAmount(amountToTransfer);
backpack.removeItem(removedFromBackpack);
}
} else {
// Se há item no cursor, adiciona ao inventário
int remaining = player.getInventory().addItem(itemToTransfer).values().stream()
.mapToInt(ItemStack::getAmount).sum();
if (remaining < amountToTransfer) {
if (trueItem.getType().name().contains("SHULKER_BOX")) {
backpack.getInternalContents().remove(internalIndex);
} else {
ItemStack removedFromBackpack = trueItem.clone();
removedFromBackpack.setAmount(amountToTransfer - remaining);
backpack.removeItem(removedFromBackpack);
}
}
}
}
} else {
// Clicado no inventário do jogador (movendo para a mochila)
backpack.addItem(clickedItem);
event.getWhoClicked().getInventory().removeItem(clickedItem);
// Clicado no inventário do jogador
if (event.getCursor() != null && !event.getCursor().getType().isAir()) {
// Há item no cursor: colocar no slot clicado
ItemStack cursorItem = event.getCursor().clone();
int amountToPlace = cursorItem.getAmount();
if (event.getClick().name().contains("RIGHT")) {
amountToPlace = 1; // Clique direito: 1 item
}
cursorItem.setAmount(amountToPlace);
event.getClickedInventory().setItem(event.getSlot(), cursorItem);
// Reduz do cursor
ItemStack newCursor = event.getCursor().clone();
newCursor.setAmount(newCursor.getAmount() - amountToPlace);
if (newCursor.getAmount() <= 0) {
newCursor = null;
}
event.getWhoClicked().setItemOnCursor(newCursor);
} else {
// Sem item no cursor: mover do inventário para mochila
if (event.isShiftClick()) {
// Shift-click: move diretamente
backpack.addItem(clickedItem);
event.getWhoClicked().getInventory().removeItem(clickedItem);
} else {
// Clique normal: move para o cursor
event.getWhoClicked().setItemOnCursor(clickedItem.clone());
event.getWhoClicked().getInventory().removeItem(clickedItem);
}
}
}
// Atualiza a GUI da mochila

View File

@@ -38,4 +38,14 @@ public class Database {
public Connection getConnection() {
return connection;
}
public void closeConnection() {
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}

View File

@@ -7,3 +7,8 @@ commands:
description: Mochila infinita pra você que fica sempre sem espaço no inventario.
usage: /backpack
aliases: [bp]
permission: backpack.use
permissions:
backpack.use:
description: Permite usar o comando /backpack
default: true

Binary file not shown.

View File

@@ -7,3 +7,8 @@ commands:
description: Mochila infinita pra você que fica sempre sem espaço no inventario.
usage: /backpack
aliases: [bp]
permission: backpack.use
permissions:
backpack.use:
description: Permite usar o comando /backpack
default: true

View File

@@ -1,5 +1,5 @@
/home/morpheus/Downloads/backpack Infinita/src/main/java/shop/morpheusnox/backpackInfinita/Backpack.java
/home/morpheus/Downloads/backpack Infinita/src/main/java/shop/morpheusnox/backpackInfinita/BackpackCommand.java
/home/morpheus/Downloads/backpack Infinita/src/main/java/shop/morpheusnox/backpackInfinita/BackpackInfinita.java
/home/morpheus/Downloads/backpack Infinita/src/main/java/shop/morpheusnox/backpackInfinita/BackpackListener.java
/home/morpheus/Downloads/backpack Infinita/src/main/java/shop/morpheusnox/backpackInfinita/Database.java
/home/morpheus/Downloads/Projetos/backpack Infinita/src/main/java/shop/morpheusnox/backpackInfinita/Backpack.java
/home/morpheus/Downloads/Projetos/backpack Infinita/src/main/java/shop/morpheusnox/backpackInfinita/BackpackCommand.java
/home/morpheus/Downloads/Projetos/backpack Infinita/src/main/java/shop/morpheusnox/backpackInfinita/BackpackInfinita.java
/home/morpheus/Downloads/Projetos/backpack Infinita/src/main/java/shop/morpheusnox/backpackInfinita/BackpackListener.java
/home/morpheus/Downloads/Projetos/backpack Infinita/src/main/java/shop/morpheusnox/backpackInfinita/Database.java