diff --git a/.gitignore b/.gitignore index 835a099..82373c4 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ /plugins/screencast/nbproject/private/ /plugins/mpchat/out/ /plugins/mpchat/dist/ +/.pitiupi/ diff --git a/README.md b/README.md index af049ac..514e9bb 100644 --- a/README.md +++ b/README.md @@ -6,20 +6,64 @@ Ferramenta **P2P** para práticas de Redes de Computadores: núcleo em Java com --- -## Início rápido (um comando) +## Como rodar -Na **raiz do repositório**: +O comando compila o núcleo, os plugins do [catálogo](plugins.registry.json) e abre a janela. Plugins, cache e logs ficam em **`.pitiupi/`** dentro da pasta do projeto. + +Depois que a janela abrir: informe **nome** e **porta** (na sala, em geral `5000`). Os dois colegas usam a mesma porta. Abra os plugins na aba **Plugins**. + +### Linux (Ubuntu instalado na máquina) + +Abra o terminal, entre na pasta do projeto e rode: ```bash -chmod +x scripts/pitiupi.sh # só na primeira vez +sudo apt install openjdk-21-jdk ant python3 +chmod +x scripts/pitiupi.sh ./scripts/pitiupi.sh run --all ``` -Compila o núcleo, os plugins do [catálogo](plugins.registry.json), cria symlinks em **`PITIUPI_HOME/plugins`** (padrão `~/pitiupi/plugins`) e abre a aplicação. +A janela é a do Java do Linux. Cabo e Wi-Fi são as placas deste computador. -1. Login: **nome** e **porta** (ex.: `5000`). -2. Abra plugins na aba **Plugins** (galeria) ou pelas ações na lista **Usuários nesta rede** (peer actions). -3. P2P no mesmo PC: segunda instância com **porta diferente** (ex.: `5001`). +### Windows + +Abra o **Prompt de Comando**: tecla Windows, digite `cmd` e pressione Enter. Entre na pasta em que o projeto foi baixado e rode: + +```bat +cd %USERPROFILE%\Downloads\pitiupi +scripts\pitiupi.cmd run --all +``` + +Se a pasta for outra, troque o `cd`. No PowerShell o comando é o mesmo: `scripts\pitiupi.cmd run --all`. + +`java`, `javac` e `ant` precisam estar no PATH. No PowerShell, o JDK: + +```powershell +winget install Microsoft.OpenJDK.17 +``` + +O Apache Ant é o zip de : extraia e acrescente a pasta `bin` ao PATH. Feche o cmd e abra de novo. + +A janela é a do Java do Windows. Cabo e Wi-Fi são as placas deste computador. + +### WSL + +Abra o **Ubuntu** do WSL (não o cmd). Entre na pasta do projeto e use o comando do Linux: + +```bash +sudo apt install openjdk-21-jdk ant python3 +chmod +x scripts/pitiupi.sh +./scripts/pitiupi.sh run --all +``` + +Se o projeto foi baixado no Windows, por exemplo em Downloads: + +```bash +cd /mnt/c/Users/SEU_USUARIO/Downloads/pitiupi +chmod +x scripts/pitiupi.sh +./scripts/pitiupi.sh run --all +``` + +A compilação usa o `javac` e o `ant` do Ubuntu. A janela abre no Windows, com as placas reais. O JDK 17 do Windows também precisa estar instalado (`winget install Microsoft.OpenJDK.17` no PowerShell). ```bash ./scripts/pitiupi.sh list # ids, categorias, JAR buildado? @@ -71,19 +115,12 @@ O núcleo carrega **todos os `*.jar`** em `PITIUPI_HOME/plugins`. Detalhes: [pit ## Pré-requisitos -| Ferramenta | Uso | +| Onde | O que instalar | | --- | --- | -| **JDK** com `javac` | Compilação **Java 17+** (núcleo e plugins usam bytecode 17) | -| **Apache Ant** | Módulos NetBeans | -| **python3** | Script `scripts/pitiupi.sh` (ler o catálogo) | +| Linux e Ubuntu do WSL | `sudo apt install openjdk-21-jdk ant python3` | +| Windows (e o Windows ao lado do WSL) | JDK 17 (`winget install Microsoft.OpenJDK.17`) e Apache Ant no PATH | -```bash -sudo apt install openjdk-21-jdk ant -./scripts/pitiupi.sh check -cd pitiupi && ant test # testes JUnit do núcleo -``` - -**GUI:** Swing — WSLg / `DISPLAY=:0`. +Conferir no Linux ou no WSL: `./scripts/pitiupi.sh check`. Testes do núcleo: `cd pitiupi && ant test`. --- @@ -105,9 +142,9 @@ Opções: `--all` (padrão), `--plugins ids`, `--category Social|Jogos|Streaming ## Teste em rede - **Mesmo PC:** duas instâncias, portas distintas (ex. 5000 e 5001). -- **Dois PCs na mesma Wi‑Fi:** mesma porta (ex. 5000), nomes diferentes, mesmos JARs em `~/pitiupi/plugins` em cada máquina. +- **Dois PCs na mesma Wi‑Fi:** mesma porta (ex. 5000), nomes diferentes. Cada um segue o caso da própria máquina em [Como rodar](#como-rodar). Linux abre o Java do Linux; Windows e WSL abrem o Java do Windows. -Ver [docs/documentation/15_testes_e_gate.md](docs/documentation/15_testes_e_gate.md) e [appendix_portas_e_multicast.md](docs/documentation/appendix_portas_e_multicast.md). +Ver [docs/documentation/15_testes_e_gate.md](docs/documentation/15_testes_e_gate.md), [appendix_portas_e_multicast.md](docs/documentation/appendix_portas_e_multicast.md) e [17_teste_com_colega.md](docs/documentation/17_teste_com_colega.md). --- diff --git a/docs/decision-register.md b/docs/decision-register.md index 9b34804..582afc3 100644 --- a/docs/decision-register.md +++ b/docs/decision-register.md @@ -10,7 +10,7 @@ | D6 | Mensagens `Serializable` em `byte[]` | Independência do transporte; plugins definem tipos | [07_mensagens_e_serializacao.md](documentation/07_mensagens_e_serializacao.md) | | D7 | Plugins via JAR + Java SPI | Carregamento dinâmico sem recompilar o núcleo | [09_sistema_de_plugins.md](documentation/09_sistema_de_plugins.md) | | D8 | Classloader por JAR de plugin | Isolar dependências; desserialização com `PluginObjectInputStream` | [09_sistema_de_plugins.md](documentation/09_sistema_de_plugins.md) | -| D9 | Plugins em `PITIUPI_HOME/plugins` | Dados do usuário fora do clone Git; `PITIUPI_HOME` ou `~/pitiupi` | [00_quickstart.md](documentation/00_quickstart.md) | +| D9 | Plugins em `PITIUPI_HOME/plugins` | Dados de execução em `.pitiupi/` na raiz do clone (não versionado). `PITIUPI_HOME` ainda pode apontar outro diretório | [00_quickstart.md](documentation/00_quickstart.md) | | D10 | Erros com `ErrorCode` | Mensagens PT na UI; `PitiupiException` no domínio | [13_guia_desenvolvimento.md](documentation/13_guia_desenvolvimento.md) | | D11 | Reinício após instalar/remover JAR | Mutar `plugins/` exige reiniciar o app para recarregar SPI | [04_inicializacao_e_gui.md](documentation/04_inicializacao_e_gui.md) | | D16 | UI em abas; sem `JFrame` de plugin | Conteúdo na `MainShellFrame`; galeria e peer actions abrem abas | [04_inicializacao_e_gui.md](documentation/04_inicializacao_e_gui.md) | @@ -27,5 +27,6 @@ | D27 | TTL padrão 1, ajustável de 1 a 32 | 1 permanece na sub-rede local; valor maior é opção de configuração | [appendix_portas_e_multicast.md](documentation/appendix_portas_e_multicast.md) | | D28 | Saída Automático, Cabo ou Wi-Fi | Multicast, IP exibido e TCP de saída usam a interface escolhida | [appendix_portas_e_multicast.md](documentation/appendix_portas_e_multicast.md) | | D29 | Connect TCP com prazo de 5 s fora da EDT | Aviso só enquanto não há socket aberto para aquele IP | [06_tcp_conexoes.md](documentation/06_tcp_conexoes.md) | +| D30 | `eth*` continua cabo, inclusive no WSL | A placa Wi-Fi do Windows não existe no Linux do WSL; reclassificar `eth` quebraria o Ubuntu nativo. Na sala o processo é o Java do Windows ou o Ubuntu instalado na máquina | [appendix_portas_e_multicast.md](documentation/appendix_portas_e_multicast.md) | Novas decisões: adicionar linha nesta tabela e detalhar no arquivo técnico correspondente. diff --git a/docs/documentation/00_quickstart.md b/docs/documentation/00_quickstart.md index 5dacfbf..435b8dd 100644 --- a/docs/documentation/00_quickstart.md +++ b/docs/documentation/00_quickstart.md @@ -1,24 +1,73 @@ # Quickstart -## Pré-requisitos +O `run --all` compila o núcleo, os plugins do catálogo e abre a janela. Plugins, cache e logs ficam em **`.pitiupi/`** na pasta do projeto. JDK **17 ou superior** (`java` e `javac`) e Apache Ant. O script do Linux também usa `python3`. -- **JDK completo** (`java` e `javac`) — **Java 17 ou superior** (17, 21 ou 25). Núcleo e plugins compilam com `javac.source/target=17`. -- Apache Ant (`pitiupi`, `plugins/chat`, `plugins/screencast`) +## Linux (Ubuntu instalado na máquina) -Ubuntu / WSL: +Abra o terminal, entre na pasta do projeto e rode: ```bash -sudo apt install openjdk-21-jdk ant -# ou: openjdk-17-jdk -which javac ant +sudo apt install openjdk-21-jdk ant python3 +chmod +x scripts/pitiupi.sh +./scripts/pitiupi.sh run --all ``` -## Build +A janela é a do Java do Linux. Cabo e Wi-Fi são as placas deste computador. -Na raiz do clone: +## Windows + +Abra o **Prompt de Comando**: tecla Windows, digite `cmd` e pressione Enter. Entre na pasta em que o projeto foi baixado e rode: + +```bat +cd %USERPROFILE%\Downloads\pitiupi +scripts\pitiupi.cmd run --all +``` + +Se a pasta for outra, troque o `cd`. No PowerShell o comando é o mesmo: `scripts\pitiupi.cmd run --all`. + +`java`, `javac` e `ant` precisam estar no PATH. No PowerShell, o JDK: + +```powershell +winget install Microsoft.OpenJDK.17 +``` + +O Apache Ant é o zip de : extraia e acrescente a pasta `bin` ao PATH. Feche o cmd e abra de novo. + +A janela é a do Java do Windows. Cabo e Wi-Fi são as placas deste computador. + +## WSL + +Abra o **Ubuntu** do WSL, não o cmd. Entre na pasta do projeto e use o comando do Linux: + +```bash +sudo apt install openjdk-21-jdk ant python3 +chmod +x scripts/pitiupi.sh +./scripts/pitiupi.sh run --all +``` + +Se o projeto foi baixado no Windows, por exemplo em Downloads: + +```bash +cd /mnt/c/Users/SEU_USUARIO/Downloads/pitiupi +chmod +x scripts/pitiupi.sh +./scripts/pitiupi.sh run --all +``` + +A compilação usa o `javac` e o `ant` do Ubuntu. A janela abre no Windows, com as placas reais, então o JDK 17 do Windows também precisa estar instalado (`winget install Microsoft.OpenJDK.17` no PowerShell). Abrir o `java` de dentro do WSL, sem esse comando, não mostra o Wi-Fi do Windows. O motivo está em [appendix_portas_e_multicast.md](appendix_portas_e_multicast.md). + +## Depois que a janela abrir + +Login com nome e porta (na sala, em geral `5000` nos dois). Abra plugins pela aba **Plugins**. Clique em **Todos** ou em um peer na lista lateral para ver as ações de cada plugin. + +Validação rápida do núcleo: `cd pitiupi && ant test`. + +## Build sem abrir a janela + +No Linux ou no WSL, na pasta do projeto: ```bash ./scripts/pitiupi.sh build --all +./scripts/pitiupi.sh link --all ``` Ou manualmente: @@ -28,21 +77,3 @@ cd pitiupi && ant jar cd plugins/chat && ant jar cd plugins/screencast && ant jar ``` - -## Instalar plugins - -Runtime: JARs em **`PITIUPI_HOME/plugins`** (padrão `~/pitiupi/plugins`). - -```bash -./scripts/pitiupi.sh link --all -``` - -## Executar - -```bash -./scripts/pitiupi.sh run --all -``` - -Login com nome e porta; abra plugins pela aba **Plugins**. Clique em **Todos** ou em um peer na lista lateral para ver ações de cada plugin. - -Validação rápida do núcleo: `cd pitiupi && ant test`. diff --git a/docs/documentation/04_inicializacao_e_gui.md b/docs/documentation/04_inicializacao_e_gui.md index aaf6279..e6ce19a 100644 --- a/docs/documentation/04_inicializacao_e_gui.md +++ b/docs/documentation/04_inicializacao_e_gui.md @@ -52,7 +52,7 @@ cd plugins/chat && ant clean jar ./scripts/pitiupi.sh link --all ``` -Isso recria o symlink `~/pitiupi/plugins/chat.jar` → o JAR buildado. O comando `link` lista o destino real de cada `.jar`. +Isso recria o symlink `.pitiupi/plugins/chat.jar` → o JAR buildado, na raiz do clone. O comando `link` lista o destino real de cada `.jar`. # Interface gráfica diff --git a/docs/documentation/05_udp_multicast.md b/docs/documentation/05_udp_multicast.md index 3615bcd..98d04a8 100644 --- a/docs/documentation/05_udp_multicast.md +++ b/docs/documentation/05_udp_multicast.md @@ -111,4 +111,4 @@ sequenceDiagram PM->>UI: receiveMessage no plugin ``` -**Falhas comuns:** firewall bloqueando UDP na porta do login; portas diferentes entre peers; isolamento de clientes no Wi‑Fi; WSL num lado e Windows nativo no outro. +**Falhas comuns:** firewall bloqueando UDP na porta do login; portas diferentes entre peers; isolamento de clientes no Wi‑Fi; um processo dentro do WSL e o outro no Java do Windows. Onde abrir a janela: [appendix_portas_e_multicast.md](appendix_portas_e_multicast.md). diff --git a/docs/documentation/15_testes_e_gate.md b/docs/documentation/15_testes_e_gate.md index 6c819ef..d4ae9aa 100644 --- a/docs/documentation/15_testes_e_gate.md +++ b/docs/documentation/15_testes_e_gate.md @@ -45,7 +45,7 @@ Depois, para runtime local: ## Testes manuais — dois PCs (mesma Wi‑Fi) -Mesma **porta** em ambos (ex. 5000), **mesmos JARs** em `~/pitiupi/plugins` em cada máquina: +Mesma **porta** em ambos (ex. 5000), **mesmos JARs** em `.pitiupi/plugins` na raiz do clone de cada máquina: - [ ] Presença e linha **Todos** - [ ] Troca de mensagens no chat (multicast e, se possível, unicast/TCP) diff --git a/docs/documentation/17_teste_com_colega.md b/docs/documentation/17_teste_com_colega.md index 3a9c69e..4155105 100644 --- a/docs/documentation/17_teste_com_colega.md +++ b/docs/documentation/17_teste_com_colega.md @@ -35,11 +35,15 @@ Substitua `5000` e o IP do colega pelos valores da aba Configurações. - Caminho: `traceroute IP` ou `tracepath IP`. Conte os saltos até o IP do colega: esse número é o TTL mínimo. - Porta TCP do aplicativo: `nc -vz -w 3 IP 5000` (ou `ncat`) +## WSL na sala + +Cada um abre o programa pelo caso da própria máquina, descrito no [quickstart](00_quickstart.md). No Linux, o terminal e `./scripts/pitiupi.sh run --all` (Java do Linux). No Windows, o cmd e `scripts\pitiupi.cmd run --all` (Java do Windows). No WSL, o terminal do Ubuntu e `./scripts/pitiupi.sh run --all` (a janela abre no Java do Windows). Os dois lados se veem. Abrir o `java` de dentro do WSL, sem esse comando, mostra só `eth0` ou `eth1`. Detalhe: [appendix_portas_e_multicast.md](appendix_portas_e_multicast.md). + ## Como ler o resultado - **O ping falha.** O problema está na rede entre os PCs: sub-rede diferente, cabo, Wi-Fi ou isolamento de clientes no roteador. O Pitiupi não contorna isso. - **O ping funciona e a porta TCP não abre.** Firewall, porta errada ou o outro Pitiupi não está escutando. Confira a porta na aba Configurações e libere UDP e TCP nessa porta. -- **O ping com TTL 1 responde e a lista só mostra Todos.** A descoberta é multicast, e um TTL baixo não é a causa quando o `tracert` tem um salto só. Confira porta igual, a mesma saída (os dois no cabo ou os dois no Wi-Fi; `169.254` e `192.168` ao mesmo tempo não se veem), firewall de UDP e isolamento de clientes. Um lado no WSL e o outro no Windows costuma impedir o multicast: os dois peers precisam estar no mesmo tipo de ambiente. +- **O ping com TTL 1 responde e a lista só mostra Todos.** A descoberta é multicast, e um TTL baixo não é a causa quando o `tracert` tem um salto só. Confira porta igual, a mesma saída (os dois no cabo ou os dois no Wi-Fi; `169.254` e `192.168` ao mesmo tempo não se veem), firewall de UDP e isolamento de clientes. Um processo aberto dentro do WSL e o outro no Java do Windows não compartilham a mesma placa: os dois precisam estar no Java do Windows ou os dois no Ubuntu instalado na máquina. Ver [appendix_portas_e_multicast.md](appendix_portas_e_multicast.md). - **O `tracert` tem mais de um salto e a lista fica vazia.** Suba o TTL em Configurações até o número de saltos (máximo 32) e aplique nos dois. Um roteador no meio só entrega o multicast se estiver disposto a encaminhar o grupo. - **O colega está na lista e o TCP avisa que não conectou.** A tentativa de abrir o socket espera no máximo cerca de **5 s** e a janela continua utilizável. Veja firewall de TCP ou se a porta mudou no meio do caminho. diff --git a/docs/documentation/appendix_portas_e_multicast.md b/docs/documentation/appendix_portas_e_multicast.md index 10a6dc9..901b6b3 100644 --- a/docs/documentation/appendix_portas_e_multicast.md +++ b/docs/documentation/appendix_portas_e_multicast.md @@ -24,12 +24,32 @@ Execute duas instâncias com **portas diferentes** (ex.: 5000 e 5001). Mesmo nom - Bloqueio de multicast em redes de visitantes ou isolamento AP→AP impede descoberta. - Em laboratório, preferir cabo ou Wi‑Fi com multicast habilitado. -## WSL2 +## Onde o processo Java roda -Executar o Pitiupi no WSL e peers no Windows (ou vice-versa) pode falhar em multicast. Preferir: +A aba **Configurações** só lista interfaces que **este** processo enxerga. O nome decide a família: `eth`, `eno`, `enp`, `ens` ou “Ethernet” é **Cabo**; `wlan`, `wlp` ou “Wi-Fi” é **Wi-Fi**. O clone Git pode ficar no disco do WSL ou numa pasta do Windows. O que muda a lista é qual `java` abre o JAR. -- todos os peers no mesmo ambiente (Linux nativo ou VMs), ou -- dois PCs físicos na mesma sub-rede. +| Processo | O que a saída mostra | +| --- | --- | +| `java.exe` do Windows | Placas reais. Sem cabo com IPv4, **Cabo** não é oferecido. **Wi-Fi** aparece quando a placa sem fio está ligada. | +| Ubuntu instalado no PC (não é WSL) | `wlan*` e `eth*`/`enp*` reais. O mesmo `./scripts/pitiupi.sh run --all` abre o Java do Linux. | +| Java de dentro do WSL | Em geral uma interface virtual `eth0` ou `eth1`. O programa classifica isso como **Cabo**, mesmo com o cabo físico desconectado e o Windows no Wi-Fi. Não existe `wlan` nesse Linux, então a saída **Wi-Fi** não aparece. | + +Dois arranjos de WSL, e nenhum dos dois substitui o Java do Windows na sala: + +- **NAT** (IP `172.x` no `ip -4 addr`): o Linux não está na rede dos colegas. Quem está em `192.168.x` ou `169.254.x` não recebe o multicast. Aumentar o TTL não coloca esse processo na LAN. +- **Rede espelhada** (o `eth*` mostra o mesmo IPv4 do Wi-Fi do Windows, por exemplo `192.168.3.x`): o rótulo **Cabo** segue o nome Linux, não o cabo da tomada. O socket ainda é o da interface virtual. A descoberta não é a mesma de um colega que abriu o Java no Windows. + +Não dá para o código “pegar a placa Wi-Fi do Windows” a partir do WSL: essa placa não está no espaço de rede do Linux. Tratar todo `eth*` como Wi-Fi quebraria o Ubuntu nativo, em que `eth` é cabo de verdade. Por isso a sala usa o mesmo tipo de processo nos dois lados: os dois no Java do Windows, ou os dois no Ubuntu instalado na máquina. Não misture um Pitiupi aberto no WSL com outro aberto no Windows. + +O passo a passo de cada máquina está no [quickstart](00_quickstart.md). + +| Onde a pessoa está | O que abrir | Comando, na pasta do projeto | +| --- | --- | --- | +| Linux (Ubuntu na máquina) | Terminal | `./scripts/pitiupi.sh run --all` — Java do Linux | +| Windows | Prompt de Comando (`cmd`) | `scripts\pitiupi.cmd run --all` — Java do Windows | +| WSL | Terminal do Ubuntu | `./scripts/pitiupi.sh run --all` — a janela abre no Java do Windows | + +No PowerShell o comando é o mesmo do cmd. Plugins, cache e logs ficam em `.pitiupi/` na pasta do projeto. JDK 17 do Windows, se faltar: `winget install Microsoft.OpenJDK.17`. No Windows o Ant também precisa estar no PATH. ## Escolha de interface (multicast) diff --git a/docs/tp/02_tutorial_ping_aula.md b/docs/tp/02_tutorial_ping_aula.md index 2e4c1fe..a53b3ea 100644 --- a/docs/tp/02_tutorial_ping_aula.md +++ b/docs/tp/02_tutorial_ping_aula.md @@ -118,7 +118,7 @@ O envio fica nos botões do painel. ## Passo 7 — Instalar e testar 1. `ant jar` → `dist/pitiupi.ping.jar`. -2. Aba **Configurações** → **Instalar JAR…** (ou copie para `~/pitiupi/plugins/`). +2. Aba **Configurações** → **Instalar JAR…** (ou copie para `.pitiupi/plugins/` na raiz do clone). 3. **Reinicie** o Pitiupi (obrigatório após mudar plugins). 4. Dois processos no mesmo PC: portas **5000** e **5001**, nomes diferentes. 5. Lista lateral → **Enviar ping para esta pessoa** → aba `↑` com IP; clique **Enviar ping** → RTT no log. diff --git a/pitiupi/plugins/README.md b/pitiupi/plugins/README.md index 3636ac1..b075bb4 100644 --- a/pitiupi/plugins/README.md +++ b/pitiupi/plugins/README.md @@ -1,6 +1,6 @@ # Plugins instalados (runtime) -O núcleo carrega **todos os arquivos `.jar`** de `PITIUPI_HOME/plugins` ao iniciar (padrão `~/pitiupi/plugins`). Variável de ambiente opcional: `PITIUPI_HOME`. +O núcleo carrega **todos os arquivos `.jar`** de `PITIUPI_HOME/plugins`. O script de execução usa **`.pitiupi/plugins`** na raiz do clone. Variável de ambiente opcional: `PITIUPI_HOME`. ## Instalação automática (recomendado) @@ -11,12 +11,12 @@ Na raiz do repositório, o catálogo [`plugins.registry.json`](../../plugins.reg ./scripts/pitiupi.sh link --all ``` -Symlinks: `{PITIUPI_HOME}/plugins/{id}.jar` → JAR buildado em `plugins/{módulo}/dist/` no clone. +Symlinks: `{raiz-do-clone}/.pitiupi/plugins/{id}.jar` → JAR buildado em `plugins/{módulo}/dist/` no clone. ## Manual ```bash -ln -sf /caminho/ao/clone/plugins/chat/dist/pitiupi.chat.jar ~/pitiupi/plugins/chat.jar +ln -sf /caminho/ao/clone/plugins/chat/dist/pitiupi.chat.jar /caminho/ao/clone/.pitiupi/plugins/chat.jar ``` Não commite `.jar` binários no Git — apenas este README. diff --git a/pitiupi/src/pitiupi/platform/PitiupiHome.java b/pitiupi/src/pitiupi/platform/PitiupiHome.java index 35d997d..f64e272 100644 --- a/pitiupi/src/pitiupi/platform/PitiupiHome.java +++ b/pitiupi/src/pitiupi/platform/PitiupiHome.java @@ -6,7 +6,7 @@ import java.nio.file.Path; import java.nio.file.Paths; /** - * Raiz de dados do usuário ({@code PITIUPI_HOME} ou {@code ~/pitiupi}). + * Raiz dos dados de execução ({@code PITIUPI_HOME}, ou {@code .pitiupi} na raiz do clone). */ public final class PitiupiHome { @@ -35,9 +35,38 @@ public final class PitiupiHome { if (env != null && !env.isBlank()) { return expandUserHome(env.trim()); } + Path inRepo = dataDirNextToClone(); + if (inRepo != null) { + return inRepo; + } return Paths.get(System.getProperty("user.home"), "pitiupi"); } + /** + * {@code .pitiupi} ao lado de {@code plugins.registry.json}, subindo a partir do JAR ou das classes. + */ + private static Path dataDirNextToClone() { + try { + var source = PitiupiHome.class.getProtectionDomain().getCodeSource(); + if (source == null || source.getLocation() == null) { + return null; + } + Path dir = Paths.get(source.getLocation().toURI()); + if (Files.isRegularFile(dir)) { + dir = dir.getParent(); + } + for (int i = 0; i < 6 && dir != null; i++) { + if (Files.isRegularFile(dir.resolve("plugins.registry.json"))) { + return dir.resolve(".pitiupi"); + } + dir = dir.getParent(); + } + } catch (Exception ignored) { + return null; + } + return null; + } + private static Path expandUserHome(String path) { if (path.startsWith("~/")) { return Paths.get(System.getProperty("user.home"), path.substring(2)); diff --git a/scripts/pitiupi.cmd b/scripts/pitiupi.cmd new file mode 100644 index 0000000..5e353b2 --- /dev/null +++ b/scripts/pitiupi.cmd @@ -0,0 +1,35 @@ +@echo off +setlocal EnableExtensions +cd /d "%~dp0.." +if /I "%~1"=="run" goto run +echo Uso: scripts\pitiupi.cmd run --all +exit /b 1 + +:run +where ant >nul 2>&1 +if errorlevel 1 ( + echo ERRO: ant nao esta no PATH. Instale o Apache Ant e o JDK 17. + exit /b 1 +) +where javac >nul 2>&1 +if errorlevel 1 ( + echo ERRO: javac nao esta no PATH. Instale o JDK 17. + exit /b 1 +) + +call ant -f "%CD%\pitiupi\build.xml" jar +if errorlevel 1 exit /b 1 + +if not exist "%CD%\.pitiupi\plugins" mkdir "%CD%\.pitiupi\plugins" +del /q "%CD%\.pitiupi\plugins\*.jar" 2>nul + +set "PITIUPI_REPO=%CD%" +set "PITIUPI_PLUGINS=%CD%\.pitiupi\plugins" +powershell.exe -NoProfile -ExecutionPolicy Bypass -Command "$repo = $env:PITIUPI_REPO; $dest = $env:PITIUPI_PLUGINS; $reg = Get-Content -Raw (Join-Path $repo 'plugins.registry.json') | ConvertFrom-Json; foreach ($p in $reg.plugins) { $dir = Join-Path $repo ($p.dir -replace '/','\'); if ($p.build -ne 'ant') { Write-Error ('build nao suportado neste prompt: ' + $p.build); exit 1 }; & ant -f (Join-Path $dir 'build.xml') jar; if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }; $src = Join-Path $dir ($p.jar -replace '/','\'); if (-not (Test-Path -LiteralPath $src)) { Write-Error ('JAR ausente: ' + $src); exit 1 }; Copy-Item -LiteralPath $src -Destination (Join-Path $dest ($p.id + '.jar')) -Force }" +if errorlevel 1 exit /b 1 + +powershell.exe -NoProfile -ExecutionPolicy Bypass -File "%~dp0run-windows.ps1" -PitiupiHome "%CD%\.pitiupi" -Jar "%CD%\pitiupi\dist\pitiupi.jar" +if errorlevel 1 exit /b 1 +echo Janela aberta no Windows. Cabo e Wi-Fi sao as placas desta maquina. +echo Plugins em %CD%\.pitiupi\plugins +exit /b 0 diff --git a/scripts/pitiupi.sh b/scripts/pitiupi.sh index 40138ce..1d3974e 100755 --- a/scripts/pitiupi.sh +++ b/scripts/pitiupi.sh @@ -4,7 +4,7 @@ set -euo pipefail REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" CORE="${REPO_ROOT}/pitiupi" -PITIUPI_HOME="${PITIUPI_HOME:-$HOME/pitiupi}" +PITIUPI_HOME="${PITIUPI_HOME:-${REPO_ROOT}/.pitiupi}" PLUGINS_DIR="${PITIUPI_HOME}/plugins" REGISTRY="${REPO_ROOT}/plugins.registry.json" export PITIUPI_HOME @@ -31,6 +31,10 @@ Exemplos: ./scripts/pitiupi.sh run --all ./scripts/pitiupi.sh run --category Social ./scripts/pitiupi.sh run --plugins chat + +Linux: no terminal, ./scripts/pitiupi.sh run --all (Java do Linux). +WSL: no terminal do Ubuntu, o mesmo comando (a janela abre no Java do Windows). +Windows: no cmd, scripts\pitiupi.cmd run --all (Java do Windows). EOF } @@ -196,7 +200,27 @@ build_plugins_from_selection() { done < <(selected_ids) } +running_on_wsl() { + [[ -r /proc/version ]] && grep -qi microsoft /proc/version +} + +running_on_git_bash() { + [[ "${OSTYPE:-}" == msys* || "${OSTYPE:-}" == mingw* ]] +} + +to_windows_path() { + if running_on_wsl && command -v wslpath >/dev/null 2>&1; then + wslpath -w "$1" + elif command -v cygpath >/dev/null 2>&1; then + cygpath -w "$1" + else + printf 'ERRO: não sei converter o caminho para o Windows: %s\n' "$1" >&2 + exit 1 + fi +} + link_plugins_from_selection() { + local mode="${1:-link}" local id dir jar_rel link_name src_abs mkdir -p "${PLUGINS_DIR}" rm -f "${PLUGINS_DIR}/"*.jar @@ -207,7 +231,15 @@ link_plugins_from_selection() { jar_rel="$(registry_python field "$id" jar)" link_name="${id}.jar" src_abs="${REPO_ROOT}/${dir}/${jar_rel}" - ln -sf "${src_abs}" "${PLUGINS_DIR}/${link_name}" + if [[ ! -f "${src_abs}" ]]; then + printf 'ERRO: JAR ausente: %s\n' "${src_abs}" >&2 + exit 1 + fi + if [[ "${mode}" == "copy" ]]; then + cp -L "${src_abs}" "${PLUGINS_DIR}/${link_name}" + else + ln -sf "${src_abs}" "${PLUGINS_DIR}/${link_name}" + fi done < <(selected_ids) local count @@ -217,12 +249,27 @@ link_plugins_from_selection() { else printf 'Plugins ativos em %s:\n' "${PLUGINS_DIR}" ls -1 "${PLUGINS_DIR}"/*.jar - for jar in "${PLUGINS_DIR}"/*.jar; do - [[ -L "$jar" ]] && printf ' -> %s\n' "$(readlink -f "$jar")" - done + if [[ "${mode}" != "copy" ]]; then + local jar + for jar in "${PLUGINS_DIR}"/*.jar; do + [[ -L "$jar" ]] && printf ' -> %s\n' "$(readlink -f "$jar")" + done + fi fi } +launch_windows_java() { + local home_win jar_win ps1 + if ! command -v powershell.exe >/dev/null 2>&1; then + printf 'ERRO: o PowerShell do Windows não está no PATH.\n' >&2 + exit 1 + fi + home_win="$(to_windows_path "${PITIUPI_HOME}")" + jar_win="$(to_windows_path "${CORE}/dist/pitiupi.jar")" + ps1="$(to_windows_path "${REPO_ROOT}/scripts/run-windows.ps1")" + powershell.exe -NoProfile -ExecutionPolicy Bypass -File "${ps1}" -PitiupiHome "${home_win}" -Jar "${jar_win}" +} + check_tools() { local ok=0 for cmd in java javac ant make python3; do @@ -323,7 +370,14 @@ case "${CMD}" in check_tools || exit 1 build_core build_plugins_from_selection - link_plugins_from_selection - exec java -jar "${CORE}/dist/pitiupi.jar" + if running_on_wsl || running_on_git_bash; then + link_plugins_from_selection copy + launch_windows_java + printf 'Janela aberta no Windows. Cabo e Wi-Fi são as placas desta máquina.\n' + printf 'Plugins em %s\n' "${PLUGINS_DIR}" + else + link_plugins_from_selection link + exec java -jar "${CORE}/dist/pitiupi.jar" + fi ;; esac diff --git a/scripts/run-windows.ps1 b/scripts/run-windows.ps1 new file mode 100644 index 0000000..f93b03f --- /dev/null +++ b/scripts/run-windows.ps1 @@ -0,0 +1,48 @@ +# Chamado por scripts/pitiupi.sh (WSL ou Git Bash) e por scripts/pitiupi.cmd. +# Não copia plugins: quem chama já deixou o JAR e o PITIUPI_HOME prontos. +param( + [Parameter(Mandatory = $true)][string]$PitiupiHome, + [Parameter(Mandatory = $true)][string]$Jar +) + +$ErrorActionPreference = 'Stop' + +function Find-JavaExe { + $cmd = Get-Command java -ErrorAction SilentlyContinue + if ($cmd -and $cmd.Source -notmatch '\\WindowsApps\\') { + return $cmd.Source + } + $patterns = @( + (Join-Path $env:ProgramFiles 'Microsoft\jdk-*\bin\java.exe'), + (Join-Path $env:ProgramFiles 'Eclipse Adoptium\jdk-*\bin\java.exe'), + (Join-Path $env:ProgramFiles 'Java\jdk-*\bin\java.exe'), + (Join-Path ${env:ProgramFiles(x86)} 'Microsoft\jdk-*\bin\java.exe'), + (Join-Path $env:LOCALAPPDATA 'Programs\Microsoft\jdk-*\bin\java.exe') + ) + foreach ($pat in $patterns) { + $hit = Get-Item -Path $pat -ErrorAction SilentlyContinue | + Sort-Object FullName -Descending | + Select-Object -First 1 + if ($hit) { return $hit.FullName } + } + return $null +} + +if (-not (Test-Path -LiteralPath $Jar)) { + Write-Error "JAR ausente: $Jar" +} +if (-not (Test-Path -LiteralPath $PitiupiHome)) { + Write-Error "PITIUPI_HOME ausente: $PitiupiHome" +} + +$javaExe = Find-JavaExe +if (-not $javaExe) { + Write-Error "Java do Windows nao encontrado. No PowerShell: winget install Microsoft.OpenJDK.17 --accept-package-agreements" +} + +Get-CimInstance Win32_Process -Filter "Name = 'java.exe' OR Name = 'javaw.exe'" -ErrorAction SilentlyContinue | + Where-Object { $_.CommandLine -and $_.CommandLine -like '*pitiupi.jar*' } | + ForEach-Object { Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue } + +$env:PITIUPI_HOME = $PitiupiHome +Start-Process -FilePath $javaExe -ArgumentList @('-jar', $Jar)