-
Ilość zawartości
536 -
Rejestracja
-
Ostatnia wizyta
-
Wygrane w rankingu
13
Treść opublikowana przez TheMolkaPL
-
Jeżeli chodzi z mojej strony to nie doświadczyłem jeszcze lagów.
-
[Network] Łatwa zmiana serwera w oknie
TheMolkaPL odpowiedział(a) na TheMolkaPL temat w W trakcie realizacji
Już nie można -
W kodzie twojego słuchacza pobierasz gracza getPlayer(), a następnie wykonujesz sendMessage(...).
-
To jest zdrzenie. Mylisz w tym momencie różnicę pomiędzy zdarzeniem (eventem), a słuchaczem (listenerem). Teraz wysłałeś zdarzenie. Przykład słuchacza wysłałem w moim pierwszym poście.
-
Przykład już podałem w moim pierwszym poście. Żadnego abstract nigdzie nie trzeba dodawać. Przecież implementujesz listener tam gdzie go definiujesz.
-
Podałem ci linka do dokumentacji - tam jest lista wszystkich zdarzeń. Klasy nie musisz stworzyć; @EventHandler jest adnotacją już w Bukkicie.
-
Przecież dałem ci linka do dokumentacji... https://hub.spigotmc.org/javadocs/spigot/
-
Będąc na stronie głównej dokumentacji zawsze znajdziemy listę package. Package to taka paczka w której znajdują się klasy. Gdy spojrzymy na package to one mają swoje specyficzne nazwy. Każdy package mówi co w sobie posiada. Przykładowo package "block" będzie posiadał bloki, package "command" komendy, itd. Ciebie interesują akurat zdarzenia, więc wchodzisz w package "event". Tutaj zwróć uwagę na to, że sam package "event" posiada jedynie klasy budujące system zdarzeń w Bukkit. Ciebie interesują ich rodzaje. Zdarzenia podzielone są na kolejne package - "event.block", "event.player", ... Taki package od razu mówi nam, że ten pierwszy posiada zdarzenia związane z blokami, drugi, że posiada zdarzenia związane z graczem. Kliknij na wybrany package a następnie pokaże się tabela z dostępnymi w tym package klasami.
-
W pluginie nie ma żadnych onPlace, onBreak ani nic z podobnych rzeczy. Plugin jest to dodatek do Bukkita, który całkowicie piszesz według swoich upodobań (musisz tylko stworzyć plik plugin.yml i klasę dziedziczącą po JavaPlugin). Oznacza to, że w pluginie znajdzie się to, co sobie zażyczysz i w jaki sposób. To co masz na myśli to prawdopodobnie zdarzenia (eventy) w Bukkicie. Przy stawianiu bloku przez gracza wywoływany jest BlockBreakEvent; przy stawianiu BlockPlaceEvent, ... Zdarzenia wykonywane są w słuchaczach (listenerach). Słuchacz jest to metoda, inaczej zbiór zadań lub instrukcji które zostaną wykonane przy wywołaniu wybranego przez ciebie eventu. Załóżmy więc, że chcesz nasłuchać zdarzenie BlockBreakEvent (wykonywany przy niszczeniu bloku przez gracza) oraz wykonać przy nim wysłanie wiadomości do wszystkich graczy. Wyglądałoby to mniej więcej tak: @EventHandler public void handleBlockBreakEvent(BlockBreakEvent event) { for (Player online : Bukkit.getOnlinePlayers()) { online.sendMessage(new TextComponent("Gracz " + event.getPlayer().getName() + " wlasnie zniszczyl blok.")); } } Teraz pozwól mi wytłumaczyć co oznacza powyższy kod. public oznacza, że ta metoda, czyli zbiór instrukcji do wykonania będzie widoczna zewsząd. Oznacza to, że ktokolwiek, lub którakolwiek klasa będzie miała do niej swobodny dostęp do jej wykonania. Istnieje jeszcze kilka innych rodzajów widoczności - default, protected oraz private. W słuchaczach (listenerach) Bukkit zaleca się jednak użycie public, bo chociaż z poziomu Bukkita zawsze będzie public, to pierwotna definicja tej metody będzie miała wpływ na prędkość załadowania słuchaczy. void oznacza, że ten zbiór instrukcji, który zostanie wykonany i nie zwróci żadnej wartości zwrotnej. Inaczej. niezależnie co w środku tej metody wykonamy, metoda poprzednia która ją wykonuje nie będzie sobie życzyć żadnej wartości zwrotnej. handleBlockBreakEvent jest losową nazwą tego zdarzenia. Bukkita nie obchodzi jak będzie się metoda nazywać; jest on jedynie identyfikatorem w twojej klasie. Możesz ją nazwać dowolnie jak chcesz, ale powinieneś śledzić zalecenia Oracle oraz Sun. Dalej przechodzimy do zawartości nawiasów - są to parametry. Są to wartości, które potrzebne są do wykonania naszej metody, w tym przypadku słuchacza (listenera). Bukkit akceptuje tutaj jedynie jeden parametr, który musi być eventem (czyli dziedziczyć po klasie Event). Dodatkowo taki event musi posiadać HandlerList i statyczną metodę getHandlerList() go zwracającą. To jednak już byłoby elementem poradnika jak tworzyć własne zdarzenia w Bukkit. Dodatkowo nad metodą znajduje się magiczne @HandlerList. Jest to adnotacja, inaczej dopisek, lub dodatkowa informacja, znacznik tej metody, zbioru instrukcji. Mówi ona Bukkitowi, że ten przy rejestracji słuchaczy (listenerów) ma wziąć ją pod uwagę w czasie skanowania metod. Wracając do pytania; prawdopodobnie szukasz listy wszystkich zdarzeń w Bukkit. Obecnie Bukkit nie jest już rozwijany, ale Spigot (jego fork, kontynuacja) dalej dodają nowe, choć niewielkie funkcje. Wszystkie zdarzenia znajdują się w dokumentacji. Co ciekawe - Bukkit wszystkie swoje zdarzenia posiada w packagu event - org.bukkit.event.... Korzystając na przykład z IDE (programu wspomagającego rozwój aplikacji) InteliiJ masz możliwość podglądu wszystkich zdarzeń, które są Bukkitowskim zdarzeniem. Po prostu przejdź do klasy Event (wciśnij kombinację klawiszy CTRL + N), wpisz tam "Event" - wybierz prawdopodobnie pierwszy wynik - Event - org.bukkit.event. Przy linijce public abstract class Event pokaże ci się niebieska ikona implementacji. Jej naciśnięcie spowoduje wyświetlenie wszystkich klas dziedziczącej po tej właśnie klasie. Mam nadzieję, że pomogłem.
-
Jesteś leniem. Ja się starałem wszystko opisać, wytłumaczyć, gdzie trzeba zwracać uwagę, co i jak można zrobić... Napisanie tego wszystko zajęło mi czas... mehhh... To już jest skrócona wersja. Napisałem to co jest najważniejsze do działania tego systemu. Dużo bardziej zaawansowany system jest już napisany w Arcade2.
-
Obecnie jedyną możliwością zmiany serwera jest powrót do lobby poprzez /lobby lub /hub oraz tam wybranie serwera. Myślę, że wygodniejszym rozwiązaniem byłoby zrobienie menu/okna identycznego z lobby pod komendą /serwery lub /serwer na każdym serwerze sieci. Dzięki temu można by zmieniać serwery bez potrzeby powrotu do lobby.
-
Siemanko Grałem sobie kilka razy na SkyWars, ale zawsze mi brakowało funkcji chatu drużynowego. Jedynym sposobem komunikacji z kolegą z drużyny jest /msg, co nie jest wygodne. Myślę także, że powinien istnieć chat globalny, gdzie można by komunikować się ze wszystkim drużynami Dodatkowo znalazłem kilka błędów: prefiks na chacie "world" na scoreboardzie zamiast nazwy mapy jest nazwa świata - "world" chat jest globalny na cały serwer drużyny na pierwszej i na drugiej mapie mają inne nazwy (red i Red, blue i Blue); myślę, że powinny być ujednolicone na tabie widać graczy spoza twojej gry; dodatkowo widać graczy z innej mapie wraz z nazwą drużyny, co jest mylące w lobby SkyWars dostaje się damage z upadku Pozdrowionka
-
Właśnie odpisałem w temacie SkyWars - Obszar bogaty post na temat jak zrobić regenerację światów. Myślę, że może się to przydać wielu osobom. Omówię tutaj dwa znane rozwiązania regeneracji, oraz podam nowy - najlepszy. Będę podawać referencję do kodu mojego pluginu Arcade2, ponieważ tam właśnie taki system "regeneracji" istnieje. Zapis zmiany stanu bloków - BŁĄD! Przy słowie "regeneracja" rozumiemy przede wszystkim powrót stanu bloków do takiego, jakie były w punkcje pierwotnym. Pierwsze rozwiązanie takiego problemu przychodzi nam rejestracja zmiany stanu wszystkich bloków. Stawiamy dirt? Informujemy, że na koordynatach X, Y oraz Z nowy blok to dirt. Na pierwszy rzut oka może się to wydawać działające, ale to nie prawda. Nigdy nie ma pewności, że wszystkie bloki zostaną zregenerowane, dodatkowo taki zapis brudzi tylko naszą pamięć RAM (jeżeli mam to robić in-memory). Musielibyśmy nasłuchiwać każdą jedną możliwą zmianę bloku w serwerze oraz ją rejestrować. Drugi problem z tego się rodzi - kiedy i jak to zregenerować? Moc obliczeniowa do wykonania tak dużego zadania jak podmiana dużej ilości bloków zużyje nam dużo CPU. Kolokwialnie rzecz ujmując regeneracja można wpłynąć znaczenia na działanie serwera, więc najlepiej byłoby to zrobić podczas gdy jest on wyłączony, lub nie ma na niej żadnych graczy. Tworzenie rzutu stanu bloków - BŁĄD! No dobrze, skoro nie działa rejestracja bloków, to może przy starcie gry zapiszmy stan wszystkich bloków świata, a potem przywróćmy je do tej wartości? Pobieranie oraz zapisanie stanu bloków będzie bardzo podobne do ich podmiany - kosztuje bardzo mocnym zużyciem zasobów serwera, więc należałoby zrobić go poza jego normalnym działaniem. Ostatecznie takie rozwiązanie odpada, ponieważ jest to także w dużej mierze powielenie rozwiązania pierwszego. Ładowanie - wyładowywanie światów - ROZWIĄZANIE! Silnik Bukkit oferuje nam możliwość ładowania i wyładowywania światów w czasie jego trwania działania. Wyładowanie świata następuje natychmiastowo, polega jedynie na usunięciu go z pamięci RAM. Ładowanie natomiast może znaczenia wpłynąć na działanie logiki serwera. Generalnie rzecz biorąc ładowanie i wyładowywanie światów jest najlepszym rozwiązaniem, ponieważ i tak będzie kosztować zużyciem mniejszej ilości zasobów, niż rzeczywista regeneracja. Wprowadzenie No dobrze - zacznijmy. Na początku prosiłbym abyśmy ustanowili w tym poście kilka słów stałych, aby nie było problemów ze zrozumieniem. Świat (world) - tym słowym mam na myśli Minecraftowy świat ładowany do serwera. W plikach świata musi znajdować się plik level.dat; tam zapisane są informacje o generatorze, ziarnie (seed), miejscu spawna, obecny spawnpoint oraz masa innych rzeczy. Mapa - tym słowem mam na myśli zbiór bloków które tworzą jakąś strukturę. Znajdują się one w chunkach, czyli dużych zbiornikach 16x16 bloków (na koordynatach X oraz Z) na pełnej wysokości świata - koordynat Y. Ładowanie świata Świat do serwera ładujemy metodą createWorld(...) z interfejsu Server. W parametrze podajemy nowy obiekt klasy WorldCreator - jest to builder, czyli budowniczy innego obiektu, gdzie jego stworzenie wykonujemy po woli wykonując po kolei jej metody. Załadowanie nowego świata można także wykonać w samym WorldCreatorze. WorldCreator jest świetnym narzędziem do wypełnienia znacznej większości ustawień świata. Zaczynami od ich ustawienia. environment(...) - ustawiamy typ świata - może to być NORMAL, THE_END lub NETHER. Dzięki temu zmienimy dużo w jego działaniu. Na przykład niebo (w netherze jest czerwone, w the endzie jest czarne z gwiazdami), oraz fizykę (w netherze nie można wylewać wody, w the endzie spawnują się tylko ender-dragony i endermany). generateStructures(...) - w parametrze podajemy wartość true/false, gdzie true ustawi nam, że na tym świecie będą się generować struktury - wioski, opuszczone kopalnie, piramidy, studnie, ... - false je wyłączy. generator(...) - ustawiamy generator z jakiego nasz nowy świat będzie korzystać. Proszę spojrzeć na metody poniżej - mamy tutaj wiele możliwości wyboru. Możemy tutaj stworzyć swój własny generator podając nasz ChunkGenerator, lub pobrać domyślny generator pluginu podając jego nazwę w Stringu. Proszę poczytać więcej o generatorach w poście niżej - to bardzo ważne! generatorSettings(...) - ustawiamy dodatkowe ustawienia generatora - nie znam do końca jego działania - nigdy z tego nie korzystałem. name(...) - podajemy nazwę naszego świata - UWAGA: nazwa świata musi znajdować się w przedziale A-Z, a-z, 0-9 oraz _ i - żadne inne znaki nie są wspomagane! seed(...) - podajemy seed - ziarenko z którego będzie korzystać nasz generator. Działa tylko przy korzystaniu z generatora vanilla! type(...) - podajemy typ naszego świata. Podajemy WorldType gdzie możemy podać świat płaski, duże biomy, oraz masę innych typów. Pozwolę sobie jeszcze pokazać jak to działa w pluginie Arcade2: https://github.com/ShootGame/Arcade2/blob/f91c4d0c2b44157ad1816c999823b7828df30161/src/main/java/pl/themolka/arcade/map/MapManager.java#L84-L90 Następnie wykonujemy metodę createWorld(), a rezultat zapisujemy w obiekcie World. W tym momencie nasz świat zostanie załadowany do pamięci serwera. Może to zająć moment, zależnie od wielkości świata. Teraz należy ustawić ostatnie ustawienia gdzie dokładniej ustawimy ten świat pod nasz serwer. setAutoSave(false) - dzięki temu nasz świat nie zapisze się przy jego wyładowaniu, oraz wyłączymy auto-save, który domyślnie wykonuje się co 5 minut (do ustawienia w bukkit.yml). setKeepSpawnInMemory(false) - domyślnie w Minecraft chunki na spawnie oraz wokół niego nie są wyładowywanie z pamięci, oraz zawsze znajdują się w pamięci podręcznej serwera. Jest to zbędny zabieg, ponieważ spawnpoint świata nie koniecznie jest spawnem mapy. setSpawnFlags(potwory, zwierzęta) - może być przydatne na mapie typu SkyWars. Dzięki temu wyłączymy możliwość spawnowania się potworów i/lub zwierząt na całym świecie. Jak to działa w Arcade2: https://github.com/ShootGame/Arcade2/blob/f91c4d0c2b44157ad1816c999823b7828df30161/src/main/java/pl/themolka/arcade/map/MapManager.java#L84-L90 I gotowe! Teraz mamy załadowany świat gotowy do gry! Wyładowywanie świata Wyładowywanie świata jest bardzo proste. Wystarczy użyć metody unloadWorld(świat, zapis). Możemy podać nazwę świata, lub obiekt World. Drugi parametr ustawiamy na false, dzięki czemu nasz świat nie zostanie zapisany. Optymalizacja światów Jak wiemy generowanie świata zużywa drastycznie dużo zasobów serwera. Aby temu zaradzić należy zrobić prosty generator który wygeneruje nam tak zwany "void", czyli pusty świat. Tutaj istnieje taki generator, który generuje nam całkowicie pusty świat -> https://github.com/ShootGame/Arcade2/blob/f91c4d0c2b44157ad1816c999823b7828df30161/src/main/java/pl/themolka/arcade/generator/VoidGenerator.java Należałoby także zoptymalizować pliki świata. Klient, serwer, mody oraz różne programy (np MCEdit) generują nam dodatkowe, zbędne pliki które możemy spokojnie usunąć. level.dat - pozostaw - tutaj zapisane są wszystkie podstawowe informacje na temat świata. region (folder) - pozostaw - tutaj znajdują się pliki, w których zapisane są chunki świata. data (folder) - pozostaw - tutaj zapisane są wszystkie wioski na mapie, oraz mapy (te które wskazują nam jakiś punkt, lub po prostu mamy w niej grafikę). Wszystko inne należy usunąć! Usuwanie zbędnych chunków Przy budowie mapy Minecraft generuje nam wszystkie chunki dookoła nas. Wiele z nich jest zbędnych ponieważ nie znajduje się na nich żaden element naszej mapy. Jest to kolejny krok naszej optymalizacji, która będzie miała wpływ na przyspieszenie ładowania świata. Ten krok należy wykonać przed powyższym "Optymalizacja światów". Przy ładowaniu świata serwer będzie nam czytał chunki które znajdują się na mapie. Odczytanie ich z pliku zajmie znacznie więcej czasu niż pobranie pustej tablicy w naszym generatorze. Zupełnie inaczej jest w generatorze vanilla - tam pobranie zapisanego świata zajmie znacznie mniej czasu, niż wygenerowanie nowego! Pamiętaj o tym! Pobieramy sobie programik MCEdit - http://www.mcedit-unified.net/ Otwieramy go Po otwarciu pokaże nam się menu główne programu Klikamy "Load Level" Wybieramy plik level.dat świata w którym chcemy usunąć zbędne chunki Klikamy "otwórz" Nasz świat zostanie załadowany Klikamy na górze programu "Chunk View"; przełączymy się dzięki temu z widoku gracza na widok z lotu ptaka. Na ekranie pojawi nam się siatka (możemy przybliżyć/oddalić świat scrollując myszką) Zaznaczamy myszką te chunki (kratki) na których znajduje się nasza mapa Po lewej stronie pokazuje nam się okienko - klikamy na nim przycisk "Prune" Wyskoczy nam okienko potwierdzające usunięcie wszystkich chunków które nie zostały zaznaczone. Proszę się upewnić czy na pewno zaznaczyliśmy te chunki na których znajduje się mapa. Następnego punktu nie da się cofnąć! Klikamy OK, chunki zostaną usunięte Gotowe, zamykamy program i przechodzimy do punktu "Optymalizacja światów"! Zakończenie Tak o to mamy całkowcie zoptymalizowany świat oraz system "regeneracji". Dobre praktyki Jest jeszcze jedna rzecz którą chciałbym zaznaczyć. Folder twojego świata w głównym folderze serwera nie zostanie usunięty. Zalecam otworzyć plik bukkit.yml, oraz w sekcji settings, dopisać world-container: '/worlds' - dzięki temu wszystkie nasze światy będą zapisywane w folderze worlds, podobnie jak pluginy w plugins. Jest to dość ukryta funkcja w Bukkicie, ponieważ nie jest domyślnie zapisane w YAMLu. Przykład: settings: world-container: '/worlds' Drugie zagadnienie to 100% pewność, że nasza mapa nie zostanie uszkodzona. zalecam w głównym folderze serwera, obok logs, plugins i worlds zrobić folder maps. Tam będziemy trzymać wszystkie światy na których znajdują się mapy. Podczas ładowania tej mapy będziemy kopiować jej pliki do folderu worlds z poziomu pluginu. Dzięki temu mamy 100% pewność, że naszej mapie (która może być wykorzystywana przez wiele serwerów jednocześnie) na pewno się nic nie stanie! Mam nadzieję, że pomogłem
- 3 odpowiedzi
-
- regeneracja
- światów
-
(i 1 więcej)
Oznaczone tagami:
-
Napisz może to jeszcze raz, ale po polsku...
-
Wystarczy zobaczyć poradnik na stronie Essentials: http://wiki.mc-ess.net/wiki/Command_Reference/Kits kits: mykit: items: - 277 1 protection:50 unbreaking:50
-
Nie - nie - nie... Ładowanie i wyładowywanie światów w Bukkit (zakładając że każda mapa lub arena (w sumie to jest to samo) istnieje na oddzielnym świecie) jest bardzo proste, aczkolwiek zużywa trochę zasobów serwera. Natomiast całe działanie serwera trzeba dobrze przestudiować oraz zoptymalizować. Spróbuję to tutaj wyjaśnić w miarę ściśle, ale od razu mówię, że mogę się trochę rozpisać. Jako, że nie znam się na skryptach, to będę pomagać sobie działaniem ze strony API Bukkita; nie wiem także czy akurat te funkcję są dostępne Skript. Będę podawać referencję do kodu mojego pluginu Arcade2, ponieważ tam właśnie taki system "regeneracji" istnieje. Zapis zmiany stanu bloków - BŁĄD! Przy słowie "regeneracja" rozumiemy przede wszystkim powrót stanu bloków do takiego, jakie były w punkcje pierwotnym. Pierwsze rozwiązanie takiego problemu przychodzi nam rejestracja zmiany stanu wszystkich bloków. Stawiamy dirt? Informujemy, że na koordynatach X, Y oraz Z nowy blok to dirt. Na pierwszy rzut oka może się to wydawać działające, ale to nie prawda. Nigdy nie ma pewności, że wszystkie bloki zostaną zregenerowane, dodatkowo taki zapis brudzi tylko naszą pamięć RAM (jeżeli mam to robić in-memory). Musielibyśmy nasłuchiwać każdą jedną możliwą zmianę bloku w serwerze oraz ją rejestrować. Drugi problem z tego się rodzi - kiedy i jak to zregenerować? Moc obliczeniowa do wykonania tak dużego zadania jak podmiana dużej ilości bloków zużyje nam dużo CPU. Kolokwialnie rzecz ujmując regeneracja można wpłynąć znaczenia na działanie serwera, więc najlepiej byłoby to zrobić podczas gdy jest on wyłączony, lub nie ma na niej żadnych graczy. Tworzenie rzutu stanu bloków - BŁĄD! No dobrze, skoro nie działa rejestracja bloków, to może przy starcie gry zapiszmy stan wszystkich bloków świata, a potem przywróćmy je do tej wartości? Pobieranie oraz zapisanie stanu bloków będzie bardzo podobne do ich podmiany - kosztuje bardzo mocnym zużyciem zasobów serwera, więc należałoby zrobić go poza jego normalnym działaniem. Ostatecznie takie rozwiązanie odpada, ponieważ jest to także w dużej mierze powielenie rozwiązania pierwszego. Ładowanie - wyładowywanie światów - ROZWIĄZANIE! Silnik Bukkit oferuje nam możliwość ładowania i wyładowywania światów w czasie jego trwania działania. Wyładowanie świata następuje natychmiastowo, polega jedynie na usunięciu go z pamięci RAM. Ładowanie natomiast może znaczenia wpłynąć na działanie logiki serwera. Generalnie rzecz biorąc ładowanie i wyładowywanie światów jest najlepszym rozwiązaniem, ponieważ i tak będzie kosztować zużyciem mniejszej ilości zasobów, niż rzeczywista regeneracja. Wprowadzenie No dobrze - zacznijmy. Na początku prosiłbym abyśmy ustanowili w tym poście kilka słów stałych, aby nie było problemów ze zrozumieniem. Świat (world) - tym słowym mam na myśli Minecraftowy świat ładowany do serwera. W plikach świata musi znajdować się plik level.dat; tam zapisane są informacje o generatorze, ziarnie (seed), miejscu spawna, obecny spawnpoint oraz masa innych rzeczy. Mapa - tym słowem mam na myśli zbiór bloków które tworzą jakąś strukturę. Znajdują się one w chunkach, czyli dużych zbiornikach 16x16 bloków (na koordynatach X oraz Z) na pełnej wysokości świata - koordynat Y. Ładowanie świata Świat do serwera ładujemy metodą createWorld(...) z interfejsu Server. W parametrze podajemy nowy obiekt klasy WorldCreator - jest to builder, czyli budowniczy innego obiektu, gdzie jego stworzenie wykonujemy po woli wykonując po kolei jej metody. Załadowanie nowego świata można także wykonać w samym WorldCreatorze. WorldCreator jest świetnym narzędziem do wypełnienia znacznej większości ustawień świata. Zaczynami od ich ustawienia. environment(...) - ustawiamy typ świata - może to być NORMAL, THE_END lub NETHER. Dzięki temu zmienimy dużo w jego działaniu. Na przykład niebo (w netherze jest czerwone, w the endzie jest czarne z gwiazdami), oraz fizykę (w netherze nie można wylewać wody, w the endzie spawnują się tylko ender-dragony i endermany). generateStructures(...) - w parametrze podajemy wartość true/false, gdzie true ustawi nam, że na tym świecie będą się generować struktury - wioski, opuszczone kopalnie, piramidy, studnie, ... - false je wyłączy. generator(...) - ustawiamy generator z jakiego nasz nowy świat będzie korzystać. Proszę spojrzeć na metody poniżej - mamy tutaj wiele możliwości wyboru. Możemy tutaj stworzyć swój własny generator podając nasz ChunkGenerator, lub pobrać domyślny generator pluginu podając jego nazwę w Stringu. Proszę poczytać więcej o generatorach w poście niżej - to bardzo ważne! generatorSettings(...) - ustawiamy dodatkowe ustawienia generatora - nie znam do końca jego działania - nigdy z tego nie korzystałem. name(...) - podajemy nazwę naszego świata - UWAGA: nazwa świata musi znajdować się w przedziale A-Z, a-z, 0-9 oraz _ i - żadne inne znaki nie są wspomagane! seed(...) - podajemy seed - ziarenko z którego będzie korzystać nasz generator. Działa tylko przy korzystaniu z generatora vanilla! type(...) - podajemy typ naszego świata. Podajemy WorldType gdzie możemy podać świat płaski, duże biomy, oraz masę innych typów. Pozwolę sobie jeszcze pokazać jak to działa w pluginie Arcade2: https://github.com/ShootGame/Arcade2/blob/f91c4d0c2b44157ad1816c999823b7828df30161/src/main/java/pl/themolka/arcade/map/MapManager.java#L84-L90 Następnie wykonujemy metodę createWorld(), a rezultat zapisujemy w obiekcie World. W tym momencie nasz świat zostanie załadowany do pamięci serwera. Może to zająć moment, zależnie od wielkości świata. Teraz należy ustawić ostatnie ustawienia gdzie dokładniej ustawimy ten świat pod nasz serwer. setAutoSave(false) - dzięki temu nasz świat nie zapisze się przy jego wyładowaniu, oraz wyłączymy auto-save, który domyślnie wykonuje się co 5 minut (do ustawienia w bukkit.yml). setKeepSpawnInMemory(false) - domyślnie w Minecraft chunki na spawnie oraz wokół niego nie są wyładowywanie z pamięci, oraz zawsze znajdują się w pamięci podręcznej serwera. Jest to zbędny zabieg, ponieważ spawnpoint świata nie koniecznie jest spawnem mapy. setSpawnFlags(potwory, zwierzęta) - może być przydatne na mapie typu SkyWars. Dzięki temu wyłączymy możliwość spawnowania się potworów i/lub zwierząt na całym świecie. Jak to działa w Arcade2: https://github.com/ShootGame/Arcade2/blob/f91c4d0c2b44157ad1816c999823b7828df30161/src/main/java/pl/themolka/arcade/map/MapManager.java#L84-L90 I gotowe! Teraz mamy załadowany świat gotowy do gry! Wyładowywanie świata Wyładowywanie świata jest bardzo proste. Wystarczy użyć metody unloadWorld(świat, zapis). Możemy podać nazwę świata, lub obiekt World. Drugi parametr ustawiamy na false, dzięki czemu nasz świat nie zostanie zapisany. Optymalizacja światów Jak wiemy generowanie świata zużywa drastycznie dużo zasobów serwera. Aby temu zaradzić należy zrobić prosty generator który wygeneruje nam tak zwany "void", czyli pusty świat. Tutaj istnieje taki generator, który generuje nam całkowicie pusty świat -> https://github.com/ShootGame/Arcade2/blob/f91c4d0c2b44157ad1816c999823b7828df30161/src/main/java/pl/themolka/arcade/generator/VoidGenerator.java Należałoby także zoptymalizować pliki świata. Klient, serwer, mody oraz różne programy (np MCEdit) generują nam dodatkowe, zbędne pliki które możemy spokojnie usunąć. level.dat - pozostaw - tutaj zapisane są wszystkie podstawowe informacje na temat świata. region (folder) - pozostaw - tutaj znajdują się pliki, w których zapisane są chunki świata. data (folder) - pozostaw - tutaj zapisane są wszystkie wioski na mapie, oraz mapy (te które wskazują nam jakiś punkt, lub po prostu mamy w niej grafikę). Wszystko inne należy usunąć! Usuwanie zbędnych chunków Przy budowie mapy Minecraft generuje nam wszystkie chunki dookoła nas. Wiele z nich jest zbędnych ponieważ nie znajduje się na nich żaden element naszej mapy. Jest to kolejny krok naszej optymalizacji, która będzie miała wpływ na przyspieszenie ładowania świata. Ten krok należy wykonać przed powyższym "Optymalizacja światów". Przy ładowaniu świata serwer będzie nam czytał chunki które znajdują się na mapie. Odczytanie ich z pliku zajmie znacznie więcej czasu niż pobranie pustej tablicy w naszym generatorze. Zupełnie inaczej jest w generatorze vanilla - tam pobranie zapisanego świata zajmie znacznie mniej czasu, niż wygenerowanie nowego! Pamiętaj o tym! Pobieramy sobie programik MCEdit - http://www.mcedit-unified.net/ Otwieramy go Po otwarciu pokaże nam się menu główne programu Klikamy "Load Level" Wybieramy plik level.dat świata w którym chcemy usunąć zbędne chunki Klikamy "otwórz" Nasz świat zostanie załadowany Klikamy na górze programu "Chunk View"; przełączymy się dzięki temu z widoku gracza na widok z lotu ptaka. Na ekranie pojawi nam się siatka (możemy przybliżyć/oddalić świat scrollując myszką) Zaznaczamy myszką te chunki (kratki) na których znajduje się nasza mapa Po lewej stronie pokazuje nam się okienko - klikamy na nim przycisk "Prune" Wyskoczy nam okienko potwierdzające usunięcie wszystkich chunków które nie zostały zaznaczone. Proszę się upewnić czy na pewno zaznaczyliśmy te chunki na których znajduje się mapa. Następnego punktu nie da się cofnąć! Klikamy OK, chunki zostaną usunięte Gotowe, zamykamy program i przechodzimy do punktu "Optymalizacja światów"! Zakończenie Tak o to mamy całkowcie zoptymalizowany świat oraz system "regeneracji". Dobre praktyki Jest jeszcze jedna rzecz którą chciałbym zaznaczyć. Folder twojego świata w głównym folderze serwera nie zostanie usunięty. Zalecam otworzyć plik bukkit.yml, oraz w sekcji settings, dopisać world-container: '/worlds' - dzięki temu wszystkie nasze światy będą zapisywane w folderze worlds, podobnie jak pluginy w plugins. Jest to dość ukryta funkcja w Bukkicie, ponieważ nie jest domyślnie zapisane w YAMLu. Przykład: settings: world-container: '/worlds' Drugie zagadnienie to 100% pewność, że nasza mapa nie zostanie uszkodzona. zalecam w głównym folderze serwera, obok logs, plugins i worlds zrobić folder maps. Tam będziemy trzymać wszystkie światy na których znajdują się mapy. Podczas ładowania tej mapy będziemy kopiować jej pliki do folderu worlds z poziomu pluginu. Dzięki temu mamy 100% pewność, że naszej mapie (która może być wykorzystywana przez wiele serwerów jednocześnie) na pewno się nic nie stanie! Mam nadzieję, że pomogłem
-
Próbujesz włączysz Essentials na niekompatybilnym do niego serwerze. Spigot jak zawsze znowu popsuł kompatybilność ze starymi pluginami. Pobierz go z Jenkinsa Spigota.
-
Musisz dostać się do tej Mapy oraz poprzez refleksje usunąć je stamtąd. Pamiętaj, że może to mieć skutki uboczne; ponieważ komendy mogą być zapisywane gdzieś indziej w kodzie Bukkita lub pluginu. Usunięcie komendy z tej właśnie mapy usunie ją z indeksu; dzięki temu nie będzie mogła być wykonana, ale nie ma pewności, że obiekt jej wykonania także zostanie wyczyszczony z pamięci.
-
To zależy na jakim typie serwera. Innych używa się na "easy hc" (dziwna nazwa, łatwy trudny? O_o), innych na skyblocku a innych na kitpvp. Nie ma jednoznacznej odpowiedzi na to pytanie. Istnieje oczywiście kilka komend z których nigdy nie korzystałem "z potrzeby", a jedynie dla sprawdzenia jak to działa; /sudo przykładowo. Generalnie rzecz biorąc Essentials pasuje praktycznie na 90% obecnie powstających serwerów; jego rozbudowany system podstawowej konfiguracji; edycja podstawowych wiadomości, ale też bogate kity, filtry czy inne funkcje jak spawnowanie mogą być właśnie na nich przydatne. Myślę, że pisanie od nowa pluginu spełniającego jeszcze bardziej podstawowe funkcje niż posiada je Essentials jest celem utopijnym, ponieważ istnieje już wiele zamienników tego typu. Dodatkowo istnieje wiele mniejszych lub większych pluginów dodające do serwera funkcje których to w Essentials nie ma - i to jest właśnie ich cel. Pluginy odpowiadają za to co robią, a nie za działanie całego serwera - dzięki ich łączeniu i ogromnej kompatybilności można tworzyć nowe tryby gier. Wracając do tematu - nie ma jednoznacznej odpowiedzi na Twoje pytanie. Wszystko zależy od trybu, a sam Essentials, choć ma wiele funkcji z których może się nie korzysta to jest to na razie najlepszy możliwy plugin na podstawowe funkcje i komendy na serwerze.
-
Źle postawiłeś dwukropek. if player has permission: "moderator": ^
-
Czyli chodzi ci o to, aby przy każdym logowaniu lub rejestracji zapisywało w pliku hacked.yml nick użytkownika, jego adres IP i hasło? Upraszczaj tematy, bo czasem jest ciężko zrozumieć.
-
A więc jakieś referencje w związku z tym? Nie wiadomo jak Cię ocenić, nie podałeś też nigdzie żadnych projektów, gdzie można by zobaczyć, że rzeczywiście "się znasz". Przynajmniej plugin, który byłby open-source, można wtedy ocenić jakość kodu.
-
Niby prosty problem, ale odpowiedź może być już trochę bardziej skomplikowana. Aplikacje/projekty korzystają z innych programów od zarządzania wersjami, w Javie prawdopodobnie najpopularniejszy jest Apache Maven. Najłatwiej rozpoznać projekt korzystający z niego z pliku pom.xml (przykładowy plik POM), w korzeniu (roocie) całego projektu, lub repozytorium. Istnieje jeszcze wiele innych podobnie działających programów jak Apache Ant (dość niepopularny), lub Gradle (zyskujący na popularności). Myślę, że wystarczająco Mavena opisujesz już Wikipedia w języku polskim. Korzystanie z programu korzystającego z takiego programu jest bardzo proste. Najpierw należy zdobyć kod źródłowy. Jeżeli znajduje się on w repozytorium Git, na przykład GitHub, GitLab lub BitBucket wystarczy sklonować - git clone <adres URL repozytorium>. Następnie po sklonowaniu wchodzimy sobie do folderu projektu cd <nazwa projektu>. Tutaj wystarczy już tylko wpisać mvn clean package. Wszystkie komendy Maven można znaleźć tu. Maven przez jakiś czas - zależnie od wielkości projektu i zależności z których korzysta spróbuje pobrać wszystkie dependency i skompilować projekt w folderze target. Gdy pojawi się komunikat "BUILD SUCCESS" wszystko zostało wykonane zgodnie z planem. Możesz już otworzyć sobie kod w dobrowolnym IDE, aby edytować. Lub po prostu zdobyć plik JAR z folderu target. Myślę, że pomogłem - pozdrawiam.
-
Nie potrzebujesz żadnych zależnych pluginów do zrobienia boss-bara. Wszystko ma przecież Spigot. https://hub.spigotmc.org/javadocs/spigot/org/bukkit/boss/package-summary.html Instancję BossBara tworzysz z Server - tutaj. Parametry: String title - treść do wyświetlenia. BarColor color - kolor boss-bara. BarStyle style - styl boss-bara, dzielisz go na sekcje, albo robisz jeden pełny (solid). BarFlag... flags - dodatkowe flagi dla boss-bara. Możesz włączyć fog, aby nie widział dali, ściemnić niebo lub włączyć muzykę ender-dragona. Resztę robisz w samym BossBarze. zarządzasz flagami flagami (dodajesz usuwasz kolejne) - https://hub.spigotmc.org/javadocs/spigot/org/bukkit/boss/BossBar.html#addFlag(org.bukkit.boss.BarFlag) zarządzasz graczami (wyświetlisz im boss-bara) - https://hub.spigotmc.org/javadocs/spigot/org/bukkit/boss/BossBar.html#addPlayer(org.bukkit.entity.Player) ustawiasz poziom (progres) - https://hub.spigotmc.org/javadocs/spigot/org/bukkit/boss/BossBar.html#setProgress(double) ukrywasz/pokazujesz - https://hub.spigotmc.org/javadocs/spigot/org/bukkit/boss/BossBar.html#setVisible(boolean) NOTE: Co ciekawe API to ma wbudowaną animację przechodzenia między poziomami. Myślę, że najlepiej jest się pobawić tym samemu. Myślę, że pomogłem
-
Robię sobie plugin na minigry Arcade. Był już taki, ale chce napisać go od nowa i zbudować w ogóle innych design, który pozwoli na jeszcze więcej funkcji. Cały kod od początku powstaje jako open-source. Można go znaleźć na GitHubie - https://github.com/ShootGame/Arcade2. Obecnie nie ma możliwości pobrania pluginu, ponieważ dopiero buduje jego strukturę. Projekt Arcade - bo tak to nazwałem - ma się składać z pluginu na mini-gry, plikami serwerowymi i kilkoma przykładowymi mapami do właśnie tych gier. Projekt od samego początku powstaje jako publiczny i z otwartym kodem źródłowym. Initial commit wprowadziłem 25 grudnia zeszłego roku. Była to 1 klasa i 22 linie kodu; dzisiaj (10/02 2016) jest to ponad 350 klas i ponad 20 000 linii kodu. Design Plugin chce napisać jak najbardziej abstrakcyjnie jak to możliwe, aby umożliwić łatwe dopisywanie nowych funkcji do pluginu. Chcę go oprzeć o moduły, które będą włączone i wyłączane w potrzebie do każdej z map. Cała logika pluginu będzie polegać na przenoszeniu się między mapami. 1. Ładowanie mapy oraz jej ustawień. 2. Włączanie modułów pluginu. 3. Przenoszenie graczy. 4. Startowanie gry. 5. Kończenie gry. 6. Wyłączanie modułów pluginu. 7. Patrz punkt 1. Każdą mapę będzie można dobrowolnie konfigurować, niezależnie od innych map. Działanie pluginu będzie oparte właśnie o te konfigurację. Folder mapy (w którym znajduje się level.dat, oraz inne pliki mapy) należy umieścić w folderze repozytorium map. Taki folder powinien posiadać plik XML map.xml z jej konfiguracją. Plugin poprzez kolejkowanie map będzie je ładował (najpierw kopiował do swojej lokalizacji światów) i uruchamiał według ustawień zawartych w konfiguracji. Cały plugin działa na modelu publikacji-subskrypcji - dla zielonych - mam dużo eventów, tak jak w Bukkit, nasłuchuje je w innych częściach kodu. Konfiguracja mapy Przykładowa konfiguracja wygląda tak - link. Obecnie mam napisaną podstawową logikę pluginu, system tasków, zarządania modułami, mapami, grami, regionami, kitami - w sumie wszystko z podstaw. Teraz to testuje i rozwijam moduły. Mam już napisany moduł na rozgrywanie meczy oraz tworzenie drużyn. Na samym początku pliku konfiguracyjnego należy zdefiniować nazwę mapy, wersję, opis (cel gry), jej autorów oraz ustawienia świata Minecraft. Do ustawień świata zalicza się - poziom trudności (easy/normal/hard/peaceful), środowisko (normal, nether, the end), pvp (włączone/wyłączone globalnie na całej mapie). Dodatkowo można także podać generator który ma być wykorzystany - domyślnie jest to void, pusty świat. Można ustawić vanilla, normalny generator (aczkolwiek zabija CPU), lub z zainstalowanego pluginu na serwerze, na przykład TerrainControl. U ustawieniach należy także podać domyślny spawn - będą się na nim spawnować przyszli obserwatorzy modułu match. Piszcie propozycję do pluginu i pomysły na jego rozwój "Game" No dobrze, ale co daje ten Arcade? Szczerze? nic... Tak... nic.. no prawie. Wprowadza on tak na prawdę zarządzanie obiektami Game, który odpowiada za trwającą rozgrywkę na serwerze. Całą resztę wprowadzają moduły, które dobrowolnie włącza się niezależnie w konfiguracjach map. Każda mapa musi posiadać plik map.xml (tak, to jest XML, nie YAML - patrz niżej). Przykładowo na mapie można włączyć moduł match. Odpowiada on za rozgrywanie meczy na mapie. Jest to odliczanie do startu (jeżeli mapa i gracze są gotowi do startu). Start meczu aż do zaliczenia wszystkich celów meczu przez minimum jedną drużynę. Zakończenie meczu - odliczanie do przeniesienia na następną mapę. Ten poziom modułu - definiujący tryb działania mapy nazwałem "środowisko" - czyli "environment". Kolejnym poziomem modułu jest "format", ale tylko w match, bo są one zależne od niego. Ten moduł definiuje tryb działania graczy na mapie. Na razie implementuje tylko drużyny, aczkolwiek w przyszłości planuje dodać FFA - Free-for-all, to znaczy - każdy gra dla siebie. Co ciekawe, taka zmiana nie powinna popsuć jakichkolwiek mini-gier! Zaprezentujmy więc te drużyny... Poniżej znajdują się dwie drużyny - Blue Team oraz Red Team. Oba mają mieć friendly-fire, to znaczy, że członkowie nie mogą się nawzajem atakować. Ilość slotów to 50, aczkolwiek moderator, lub inna osoba z dodatkowym uprawnieniem może wejść nawet jeśli są pełne. Ostateczne ograniczenie to przepełnienie - overfill. Po przepełnieniu do drużyny nie może wejść już żadna osoba. <teams> <team id="blue-team" name="Blue Team" color="blue" friendly-fire="true" slots="50" overfill="60"> <kits> <kit>spawn-kit</kit> </kits> <spawns> <region yaw="90"> <cuboid min-x="43" min-y="25" min-z="-69" max-x="60" max-y="25" max-z="-62" /> </region> </spawns> </team> <team id="red-team" name="Red Team" color="red" friendly-fire="true" slots="50" overfill="60"> <kits> <kit>spawn-kit</kit> </kits> <spawns> <region yaw="270"> <cuboid min-x="-59" min-y="25" min-z="63" max-x="-42" max-y="25" max-z="70" /> </region> </spawns> </team> </teams> Kolejnym poziomem modułu meczu to cele, czyli objectives. Wszystkie inne są najniższym poziomem modułów i nie wpływają aż tak bardzo na rozgrywkę. Cele to inaczej gry, ale dlaczego nie games? Ponieważ plugin Arcade wprowadza możliwość ich mieszania! Można wymieszać Destroy The Core i Destroy The Monument jednocześnie! Dzięki temu drużyna musi zniszczyć rdzeń(ie) i monument(y) przeciwnika, aby wygrać mecz. Dzięki temu, jak i systemowi modułów każda mapa może stworzyć unikalną, niepowtarzalną mini-grę. Gry Napisałem już w pełni działający Destroy The Core. Zadaniem Twojej drużyny jest zniszczenie rdzenia drużyny przeciwnej, przy czym musisz chronić także swój. Przeciwnik ma identyczne zadanie. Rdzeń to najczęściej kula z obsidianu zalana w środku lawą. Aby wygrać, lawa musi wylać się poza rdzeń ilość bloków zdefiniowaną w konfiguracji mapy. Drużyna do której rdzeń należy może oczywiście wyciek lawy zatamować. Może zablokować go wstawieniem z powrotem bloku w miejsce wycieku. To wszystko tworzy niesamowitą rozgrywkę walki dwóch (lub więcej) drużyn. Przykładowa konfiguracja dwóch rdzeni - jeden należy do blue-team, drugi do red-team. Wygrana nastąpi po wycieku lawy 8 bloków poniżej rdzenia. Oba rdzenie nazywają się "Core". Materiał rdzenia nie jest podany, oznacza to, że będzie to obsidian. Typ cieczy nie jest podany, oznacza to, że plugin sam wykryje co znajduje się w jego wnętrzu - akceptowane ciecze (lawa i woda). <leak> <leakable id="blue-core" name="Core" owner="blue-team" detector-level="8"> <region> <cuboid min-x="11" min-y="26" min-z="-53" max-x="17" max-y="32" max-z="-47" /> </region> </leakable> <leakable id="red-core" name="Core" owner="red-team" detector-level="8"> <region> <cuboid min-x="-16" min-y="26" min-z="48" max-x="-10" max-y="32" max-z="54" /> </region> </leakable> </leak> Napisałem już także Deathmatch, z czego na razie działa Team-deathmatch, z tego względu, że napisałem na razie jedynie moduł na drużyny jako format meczu. Deathmatch oparty jest o punkty. Punkty zdobywa się za zabicie. <score> <kills>1</kills> <!-- Za zabicie otrzymuje się 1 punkt --> <limit>250</limit> <!-- Wygrana po zdobyciu 250 punktów --> </score> Następne gry jakie chciałbym zaimplementować to między innymi Destroy The Monument. XML... użyj lepiej YAMLa... YAML jest świetnym systemem zapisu, ale ma spore ograniczenia. XML jest łatwo rozbudowywalny poprzez skoncentrowanie całej struktury na elementach. Dodatkowo w XML można upchać znacznie więcej informacji, niż w YAML. YAML do potrzeb jakie stawia sobie Arcade jest po prostu niewystarczający... Dlatego zdecydowałem się na XML. Potem opisze jeszcze system regionów i filtrów. Na razie mi się nie chce Pozdrawiam A tak szczerze to wątpię, że ktoś to całe przeczytał. Pobierz: Aktualnie plugin jest we wczesnej wersji deweloperskiej. W związku z tym nie chce dawać pobierania, bo po prostu się do normalnego uruchomienia nie nadaje, a ja jeszcze nie chce się bawić w wersjonizację na tym etapie rozwoju. Kod źródłowy: https://github.com/ShootGame/Arcade2
