diff --git a/.gitignore b/.gitignore index 8ef7f96804..e6c2c69393 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,7 @@ nbproject FreeCol.log FreeCol*.jar src/*.MF +build/ build/installer/ build/net/ doc/specification_*.html diff --git a/.travis.yml b/.travis.yml index c518403831..b55ceba1e3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,12 +8,15 @@ addons: packages: - ant-optional before_install: + - .travis/install-sbom-tools.sh - if [[ "$TRAVIS_BRANCH" == "master" && "$TRAVIS_EVENT_TYPE" == "cron" ]]; then .travis/merge-sourceforge.sh; fi - if [[ "$TRAVIS_BRANCH" == "slim" && "$TRAVIS_EVENT_TYPE" == "cron" ]]; then .travis/merge-slim.sh; fi - if [[ "$TRAVIS_BRANCH" == "master" && "$TRAVIS_EVENT_TYPE" == "cron" ]]; then .travis/deploy-sourceforge-merge.sh; fi - if [[ "$TRAVIS_BRANCH" == "slim" && "$TRAVIS_EVENT_TYPE" == "cron" ]]; then .travis/deploy-slim-merge.sh; fi script: - ant testci + - if [[ "$TRAVIS_EVENT_TYPE" == "cron" ]]; then ./scripts/generate-sbom.sh; fi + - if [[ "$TRAVIS_EVENT_TYPE" == "cron" ]]; then ./scripts/scan-sbom.sh; fi before_deploy: - ant nightly-release - ls -l dist/releases diff --git a/.travis/install-sbom-tools.sh b/.travis/install-sbom-tools.sh new file mode 100755 index 0000000000..32df47eecb --- /dev/null +++ b/.travis/install-sbom-tools.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash +set -euo pipefail + +curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b "$HOME/bin" +curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sh -s -- -b "$HOME/bin" +export PATH="$HOME/bin:$PATH" diff --git a/build.xml b/build.xml index 2c89289487..1ebf46cb7e 100755 --- a/build.xml +++ b/build.xml @@ -3,7 +3,7 @@ - + This file includes targets for building FreeCol, the metaserver, distribution packages, running tests @@ -33,6 +33,10 @@ value="jars/miglayout-core-5.3.jar"/> + + + + @@ -51,6 +55,7 @@ + @@ -64,6 +69,16 @@ + + + + + + + + + + @@ -91,6 +106,12 @@ classname="net.charabia.jsmoothgen.ant.JSmoothGen" classpath="${freecol.build.dir}/jars/jsmoothgen-ant.jar"/> + + + + @@ -106,8 +127,7 @@ debug="on" optimize="on" deprecation="off" - source="${java.target.version}" - target="${java.target.version}" + release="${java.target.version}" includeantruntime="false"> @@ -125,8 +145,7 @@ debug="on" optimize="on" deprecation="off" - source="${java.target.version}" - target="${java.target.version}" + release="${java.target.version}" includeantruntime="false"> @@ -702,6 +721,7 @@ private="true" classpathref="freecol.build.classpath" Author="true" + additionalparam="-Xdoclint:all,-missing" Windowtitle="FreeCol Code Documentation"/> @@ -788,6 +808,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/jars/standalone-compiler.jar b/build/jars/standalone-compiler.jar index bbc08109dd..9b3838a4f5 100644 Binary files a/build/jars/standalone-compiler.jar and b/build/jars/standalone-compiler.jar differ diff --git a/data/strings/FreeColMessages_ar.properties b/data/strings/FreeColMessages_ar.properties index 2078337d1c..489a552ec7 100644 --- a/data/strings/FreeColMessages_ar.properties +++ b/data/strings/FreeColMessages_ar.properties @@ -88,7 +88,7 @@ reset=إعادة ضبط revertToDefaults=ارجع إلى الإعدادات الافتراضية save=حفظ scope=نطاق -select=تحديد +select=اختر server=الخادم skip=تجاوز small=صغير diff --git a/data/strings/FreeColMessages_be-tarask.properties b/data/strings/FreeColMessages_be-tarask.properties index c20ce8d047..c99434870b 100644 --- a/data/strings/FreeColMessages_be-tarask.properties +++ b/data/strings/FreeColMessages_be-tarask.properties @@ -63,7 +63,7 @@ reject=Адмовіцца remove=Выдаліць rename=Перайменаваць reset=Скінуць -revertToDefaults=Скінуць на дапомныя +revertToDefaults=Вярнуць перадвызначаныя save=Захаваць scope=Абшар select=Выбраць @@ -185,11 +185,11 @@ cli.clientOptions=XML-файл з наладамі карыстальніцка cli.debug-run=запусьціць N ход/хады/хадоў у бясьпечным рэжыме, з магчымасьцю захаваньня і выхаду cli.debug-start=неадкладна пачаць новую аднакарыстальніцкую гульню cli.debug=устанавіць рэжым наладкі FreeCol (%modes%) -cli.default-locale=устанавіць па змоўчваньні лякалізацыю (МОВА[_КРАІНА[_ВАРЫЯНТ]]) +cli.default-locale=перадвызначыць лякалізацыю (МОВА[_КРАІНА[_ВАРЫЯНТ]]) cli.difficulty=задаць узровень СКЛАДАНАСЬЦІ cli.european-count=задаць колькасьць дазволеных нацыяў (каляніяльных ЭЎРАПЕЙЦАЎ) cli.fast=прапусьціць усе дыялёгі наладаў -cli.font=устанавіць шрыфт па змоўчваньні +cli.font=перадвызначыць шрыфт cli.freecol-data=устанавіць ДЫРЭКТОРЫЮ зьвестак FreeCol (мае паддырэкторыю з назвай «base») cli.full-screen=запусьціць FreeCol у поўнаэкранным рэжыме cli.gui-scale=маштабаваць элемэнты GUI зь неабавязковым парамэтрам SCALE (%scales%) @@ -197,7 +197,7 @@ cli.headless=запуск без графічнага рэжыму cli.help=паказаць гэты экран дапамогі cli.load-savegame=загрузіць пададзены ФАЙЛ захаванай гульні cli.log-console=накіроўваць запісы ў журнале ў кансоль у дадатак да файла -cli.log-file=устанавіць файл журнала FreeCol (па змоўчваньні FreeCol.log) +cli.log-file=устанавіць файл журнала FreeCol (перадвызначана: FreeCol.log) cli.log-level=устанавіць узровень журнала Java у УЗРОВЕНЬ_ЖУРНАЛА cli.meta-server=задаць АДРАС і ПОРТ мэта-сэрвэру cli.name=пазначце ІМЯ гульца @@ -839,7 +839,7 @@ clientOptions.display.name=Экран clientOptions.display.shortDescription=Налады разрозьненьня, памеру і прадукцыйнасьці. model.option.fullscreenDisplayMode.name=Поўнаэкранны рэжым выяўленьня model.option.fullscreenDisplayMode.shortDescription=Разрозьненьне, частасьць абнаўленьня і бітавая глыбіня пры запуску ў поўнаэкранным рэжыме. -model.option.fullscreenDisplayMode.automatic=Дапомна +model.option.fullscreenDisplayMode.automatic=Перадвызначана model.option.displayScaling.name=Маштабаваньне дысплэю model.option.displayScaling.shortDescription=Вызначае памер панэляў фіксаванага памеру, такіх як міні-мапа. model.option.displayScaling.automatic=Аўтаматычна @@ -879,13 +879,13 @@ model.option.autoScroll.shortDescription=Уключыць аўтаматычну model.option.displayCompassRose.name=Паказваць кола компаса model.option.displayCompassRose.shortDescription=Ці паказваць кола компаса. model.option.displayMapControls.name=Паказваць інструмэнты кіраваньня мапай -model.option.displayMapControls.shortDescription=Ці паказваць інструмэнты кіраваньня мапай па змоўчваньні. +model.option.displayMapControls.shortDescription=Ці перадвызначана паказваць інструмэнты кіраваньня мапай. model.option.displayGrid.name=паказваць сетку -model.option.displayGrid.shortDescription=Ці паказваць сетку па змоўчваньні. +model.option.displayGrid.shortDescription=Ці перадвызначана паказваць сетку. model.option.displayBorders.name=Паказваць межы -model.option.displayBorders.shortDescription=Ці паказваць межы па змоўчваньні. +model.option.displayBorders.shortDescription=Ці перадвызначана паказваць межы. model.option.displayFogOfWar.name=Паказваць туман вайны -model.option.displayFogOfWar.shortDescription=Паказваць туман вайны на клетках па-за клеткамі бачнасьці Вашых адзінак. +model.option.displayFogOfWar.shortDescription=Ці перадвызначана паказваць туман вайны на клетках па-за клеткамі бачнасьці вашых адзінак. model.option.unitLastMoveDelay.name=Затрымка апошняга руху адзінкі model.option.unitLastMoveDelay.shortDescription=Ці рабіць кароткую затрымку на апошнім руху адзінкі. model.option.usePixmaps.name=Выкарыстоўваць піксэльныя мапы для захаваньня выяваў @@ -953,8 +953,8 @@ clientOptions.gui.colonyComparator.bySize.name=Памер clientOptions.gui.colonyComparator.bySize.shortDescription=Ад найвялікшага да найменшага clientOptions.gui.colonyComparator.bySoL.name=Сыны Волі clientOptions.gui.colonyComparator.bySoL.shortDescription=Сартаваць паводле зьмяншэньня свабоды -model.option.defaultZoomLevel.name=Маштаб па змоўчваньні -model.option.defaultZoomLevel.shortDescription=Які маштаб ужываецца для мініятурнай мапы па змоўчваньні +model.option.defaultZoomLevel.name=Перадвызначаны маштаб +model.option.defaultZoomLevel.shortDescription=Які перадвызначаны маштаб ужываецца для мініятурнай мапы. model.option.graphicsQuality.name=Якасьць рэндэрынгу графікі model.option.graphicsQuality.shortDescription=Задае якасьць пры візуалізацыі графікі. Выбар вышэйшай якасьці можа спрычыніць дзёрганьне анімацыі і/або затрымкі пры націсканьні на мапу. clientOptions.gui.graphicsQuality.lowest=Найніжэйшая @@ -1075,8 +1075,8 @@ model.option.lastTurnName.shortDescription=Аснова для назвы фай model.option.beforeLastTurnName.name=Назва файлу перад апошнім ходам model.option.beforeLastTurnName.shortDescription=Аснова для назвы файлу захаваньня перад апошнім ходам. clientOptions.warehouse.name=Устаноўкі сховішча -clientOptions.warehouse.shortDescription=Зьмяняе устаноўкі па змоўчваньні для сховішчаў і мытняў. -model.option.customStock.name=Велічыня мытні па змоўчваньні +clientOptions.warehouse.shortDescription=Зьмяняе перадвызначаныя налады для сховішчаў і мытняў. +model.option.customStock.name=Перадвызначаная велічыня мытні model.option.customStock.shortDescription=Колькасьць тавараў, якая пакідаецца ў мытні пры іх продажы. model.option.lowLevel.name=Папярэджаньне пра нізкі ўзровень model.option.lowLevel.shortDescription=Папярэджваць, калі колькасьць тавараў будзе ніжэй гэтага ўзроўню. @@ -1750,7 +1750,7 @@ model.resource.tobacco.description=Глеба гэтых лугоў выдатн model.role.name=Роля model.role.armedBrave.name=Узброены сьмялец model.role.cavalry.name=Кавалерыя -model.role.default.name=Дапомна +model.role.default.name=Перадвызначана model.role.dragoon.name=Драгун model.role.dragoon.noequipment=няма мушкетаў model.role.infantry.name=Пяхота @@ -1791,7 +1791,7 @@ model.settlement.city.plural=Горад model.settlement.colony.capital.name=Калёнія model.settlement.colony.name=Калёнія model.settlement.colony.plural=калёніі -model.settlement.default.name=Дапомна +model.settlement.default.name=Перадвызначана model.settlement.inca.capital.name=Горад інкаў model.settlement.inca.name=Горад інкаў model.settlement.inca.plural=гарады @@ -2125,7 +2125,7 @@ model.nation.austrian.name={{tag:|country=Аўстрыя|people=Аўстрыйц model.advantages.none.name=Няма model.advantages.none.shortDescription=Ніякіх перавагаў для якіх-кольвек нацыяў. Галоўным чынам прызначанае для шматкарыстальніцкіх гульняў. model.advantages.fixed.name=Фіксавана -model.advantages.fixed.shortDescription=Усе нацыі карыстаюцца сваімі дапомнымі перавагамі. Гэта патрэбна дзеля эмуляцыі арыгінальнай гульні. +model.advantages.fixed.shortDescription=Усе нацыі карыстаюцца сваімі перадвызначанымі перавагамі. Гэта патрэбна для эмуляцыі арыгінальнай гульні. model.advantages.selectable.name=На выбар model.advantages.selectable.shortDescription=Перавагі нацыяў можна абіраць, яны могуць быць неўнікальнымі. model.nationState.aiOnly.name=толькі кампутар @@ -2671,7 +2671,7 @@ colopedia.goods.madeFrom=Вырабляецца з: colopedia.goods.makes=Выкарыстоўваецца для вытворчасьці: colopedia.goods.units=Адзінкі: colopedia.nation.currentAdvantage=Цяперашняя перавага: -colopedia.nation.defaultAdvantage=Перавага па змоўчваньні: +colopedia.nation.defaultAdvantage=Перадвызначаная перавага: colopedia.nation.ruler=Уладар: colopedia.nationType.aggressionLevel.average=Сярэдняя colopedia.nationType.aggressionLevel.high=Высокая diff --git a/data/strings/FreeColMessages_id.properties b/data/strings/FreeColMessages_id.properties index 92d67001f8..e35dc2ab03 100644 --- a/data/strings/FreeColMessages_id.properties +++ b/data/strings/FreeColMessages_id.properties @@ -14,6 +14,7 @@ # Author: LittleTerserah # Author: Macofe # Author: MarioMS +# Author: Penyuwangi # Author: Rex # Author: Veracious @@ -21,7 +22,7 @@ chilly=Dingin Sekali cold=Dingin dry=Kering hot=Panas -temperate=Temperatur +temperate=Sedang veryDry=Sangat Kering veryHigh=Sangat Tinggi veryLarge=Sangat Besar @@ -31,23 +32,23 @@ veryWet=Sangat Basah warm=Hangat wet=Basah freecol.desktopEntry.GenericName=Permainan Strategi -freecol.desktopEntry.Comment=Permainan strategi bergilir yang berdasarkan dari "Sid Meier's Colonization". +freecol.desktopEntry.Comment=Permainan strategi bergilir yang berdasarkan "Sid Meier's Colonization". accept=Terima all=Semua and=dan -browse=Cari +browse=Telusuri cancel=Batalkan -client=Klien +client=Kelayan close=Tutup color=Warna connect=Sambungkan -current=Terkini +current=Kini false=Keliru fill=Isi height=Tinggi help=Bantuan high=Tinggi -host=Host +host=Inang income=pendapatan large=Besar load=Muatkan @@ -64,18 +65,18 @@ normal=Normal nothing=Tidak ada ok=OK options=Pilihan -port=Port -private=Pribadi +port=Porta +private=pribadi quit=Keluar reject=Tolak remove=Hapus rename=Ubah nama -reset=Reset -revertToDefaults=Kembalikan seperti tetapan +reset=Atur ulang +revertToDefaults=Kembalikan ke bawaan save=Simpan scope=Cakupan select=Pilih -server=Server: +server=Peladen skip=Lewati small=Kecil statistics=Statistik @@ -87,8 +88,8 @@ value=Nilai width=Lebar yes=Ya abilities=Kemampuan -activateAllUnits=Aktifkan semua unit -activateUnit=Aktifkan unit +activateAllUnits=Nyalakan semua satuan +activateUnit=Nyalakan satuan assignTradeRoute=Tetapkan rute perdagangan building=Bangunan capital=Modal @@ -139,8 +140,8 @@ startGame=Mulai Permainan tax=Pajak train=Latih unexplored=Belum dijelajahi -unitType=Tipe Unit -units=Unit +unitType=Jenis Satuan +units=Satuan list.add=Tambahkan list.down=Bawah list.edit=Sunting @@ -178,10 +179,10 @@ cli.error.home.noRead=%string% tidak dapat dibaca cli.error.home.noWrite=%string% tidak bisa ditulis cli.error.home.notDir=%string% bukan direktori. cli.error.home.notExists=Direktory %string% tidak ada -cli.error.meta-server=bukan alamat meta-server yang valid: %arg% +cli.error.meta-server=bukan alamat meta-peladen yang sah: %arg% cli.error.save=Permainan tersimpan %string% tidak dapat dibaca cli.error.serverPort=%string% bukanlah nomor port yang valid -cli.error.serverIp=%string% bukan alamat IP yang valid untuk server. +cli.error.serverIp=%string% bukan alamat IP yang sah untuk peladen. cli.error.splash=File splash %name% tidak ditemukan cli.error.timeout=%string% terlalu pendek(kurang dari %minimum%) cli.advantages=tetapkan tipe KELEBIHAN (%advantages%) @@ -207,23 +208,23 @@ cli.load-savegame=memuat BERKAS permainan tersimpan yang diberikan cli.log-console=log ke konsol selain ke berkas cli.log-file=tetapkan berkas log FreeCol (FreeCol.log sebagai default) cli.log-level=tetapkan tingkat log java ke LOGLEVEL -cli.meta-server=tetapkan ALAMAT dan PORT untuk meta-server +cli.meta-server=atur ALAMAT dan PORTA untuk meta-peladen cli.name=berikan sebuah NAMA untuk pemain cli.no-intro=lewati video pembuka cli.no-java-check=lewati pemeriksaan versi Java cli.no-memory-check=lewati pemeriksaan memori cli.no-sound=jalankan FreeCol tanpa suara cli.no-splash=lewati layar splash -cli.private=memulai sebuah server pribadi (tidak diterbitkan ke dalam metaserver) +cli.private=memulai sebuah peladen pribadi (tidak diterbitkan ke metaserver) cli.rules=memuat aturan dengan NAMA yang diberikan cli.seed=berikan BENIH untuk generator nomor pseudo-random -cli.server=memulai sebuah server yang berdiri sendiri -cli.server-name=tentukan NAMA khusus untuk server -cli.server-port=tentukan PORT khusus untuk server -cli.server-ip=tentukan IP pengikat untuk server +cli.server=memulai sebuah peladen yang berdiri sendiri +cli.server-name=tentukan NAMA khusus untuk peladen +cli.server-port=tentukan PORTA khusus untuk peladen +cli.server-ip=tentukan IP pengikat untuk peladen cli.splash=tunjukkan BERKAS gambar layar splash ketika memuat permainan cli.tc=Memuat konversi total dengan NAMA yang diberikan -cli.timeout=Jumlah detik untuk server menunggu jawaban ke pertanyaan +cli.timeout=Jumlah detik untuk peladen menunggu jawaban ke pertanyaan cli.user-cache-directory=tetapkan DIRECTORY cache pengguna FreeCol cli.user-config-directory=tetapkan konfigurasi DIREKTORI pengguna FreeCol cli.user-data-directory=tetapkan data DIREKTORI pengguna FreeCol @@ -253,10 +254,10 @@ menuBar.debug.displayErrorMessage=Tunjukkan pesan error menuBar.debug.displayEuropeStatus=Tunjukkan status Eropa menuBar.debug.displayMonarchPanel=Tunjukkan panel Raja menuBar.debug.displayPanels=Tunjukkan panel -menuBar.debug.displayUnits=Tunjukkan unit +menuBar.debug.displayUnits=Tampilkan satuan menuBar.debug.hideEntireMap=Sembunyikan Seluruh Peta menuBar.debug.memoryManager.gc=Jalankan Pengumpul Sampah -menuBar.debug.memoryManager=Manajer Memori +menuBar.debug.memoryManager=Pengelola Memori menuBar.debug.revealEntireMap=Tampilkan Seluruh Peta menuBar.debug.runMonarch=Tetapkan aksi Raja selanjutnya menuBar.debug.searchTrace=Jejak pencarian log lengkap @@ -269,13 +270,13 @@ menuBar.debug.stepRandomNumberGenerator=Laksanakan Generator nomor acak menuBar.debug.stopSkippingTurns=Berhenti melewati giliran menuBar.debug.useAI=Pakai AI aboutAction.name=Tentang FreeCol -activeAction.name=Aktifkan Unit +activeAction.name=Nyalakan Satuan assignTradeRouteAction.name=Tetapkan Rute Dagang buildColonyAction.name=Bangun / Gabung Koloni centerAction.name=Tengah changeAction.enterColony.name=Masuk Koloni -changeAction.name=Unit Selanjutnya pada Ubin -changeAction.nextUnitOnTile.name=Unit Selanjutnya pada Ubin +changeAction.name=Satuan Selanjutnya pada Ubin +changeAction.nextUnitOnTile.name=Satuan Selanjutnya pada Ubin changeAction.selectCarrier.name=Pilih Pengangkut changeWindowedModeAction.name=Mode Layar Penuh chatAction.name=Mengobrol @@ -289,7 +290,7 @@ colopediaAction.nations.name=Bangsa colopediaAction.nationTypes.name=Kelebihan Bangsa colopediaAction.resources.name=Sumber Bonus colopediaAction.terrain.name=Jenis Medan -colopediaAction.units.name=Unit +colopediaAction.units.name=Satuan colopediaAction.name=%object% (Colopedia) continueAction.name=Lanjutkan Bermain debugAction.name=Beralih mode debug @@ -382,7 +383,7 @@ tilePopupAction.name=Tampilkan Petak toggleViewModeAction.name=Alihkan Mode Tampilan tradeRouteAction.name=Rute Dagang unloadAction.name=Menurunkan muatan -waitAction.name=Tunggu/Unit Berikutnya +waitAction.name=Tunggu/Satuan Berikutnya zoomInAction.name=Perbesar zoomOutAction.name=Perkecil actionManager.name=Akselerasi Papan Ketik @@ -402,12 +403,12 @@ model.option.recruitPriceIncrease.name=Penaikan harga perekrutan model.option.recruitPriceIncrease.shortDescription=Meningkatkan biaya perekrutan imigran baru. model.option.lowerCapIncrease.name=Peningkatan batas bawah model.option.lowerCapIncrease.shortDescription=Meningkatkan harga rekrutmen minimum untuk setiap imigran baru. -model.option.priceIncreasePerType.name=Kenaikan harga per tipe unit -model.option.priceIncreasePerType.shortDescription=Apakah kenaikan harga berlaku untuk masing-masing jenis unit. +model.option.priceIncreasePerType.name=Kenaikan harga per jenis satuan +model.option.priceIncreasePerType.shortDescription=Apakah kenaikan harga berlaku untuk masing-masing jenis satuan. model.option.priceIncrease.artillery.name=Kenaikan harga meriam model.option.priceIncrease.artillery.shortDescription=menaikan harga untuk setiap meriam baru. -model.option.expertStartingUnits.name=Unit ahli awal -model.option.expertStartingUnits.shortDescription=Buat semua unit awal ahli. +model.option.expertStartingUnits.name=Satuan awal ahli +model.option.expertStartingUnits.shortDescription=Buat semua satuan awal ahli. model.option.immigrants.name=Imigran model.option.immigrants.shortDescription=Para imigran pertama dari Eropa. model.difficulty.natives.name=Pribumi @@ -464,15 +465,15 @@ model.option.interventionBells.shortDescription=Jumlah Lonceng yang diperlukan u model.option.interventionTurns.name=Giliran Intervensi model.option.interventionTurns.shortDescription=Jumlah giliran antara penambahan Pasukan Intervensi. model.option.refSize.name=Ukuran Pasukan Ekspedisi Kerajaan -model.option.refSize.shortDescription=Jumlah dan jenis unit Angkatan Ekspedisi Kerajaan. +model.option.refSize.shortDescription=Jumlah dan jenis satuan Angkatan Ekspedisi Kerajaan. model.option.refSize.soldiers.name=Infanteri -model.option.refSize.soldiers.shortDescription=Jumlah unit infanteri. +model.option.refSize.soldiers.shortDescription=Jumlah satuan infanteri. model.option.refSize.dragoons.name=Kavaleri -model.option.refSize.dragoons.shortDescription=Jumlah unit Kavaleri. +model.option.refSize.dragoons.shortDescription=Jumlah satuan Kavaleri. model.option.refSize.menOfWar.name=Men'O'War model.option.refSize.menOfWar.shortDescription=Jumlah kapal perang, atau "Men'O'War". model.option.refSize.artillery.name=Artileri -model.option.refSize.artillery.shortDescription=Jumlah unit Artileri. +model.option.refSize.artillery.shortDescription=Jumlah satuan Artileri. model.option.interventionForce.name=Kekuatan Intervensi model.option.interventionForce.shortDescription=Pasukan Intervensi dikirim untuk mendukung Perang Kemerdekaan Anda. model.option.mercenaryForce.name=Pasukan Tentara Bayaran @@ -497,8 +498,8 @@ model.option.foundingFatherFactor.name=Faktor bapak pendiri model.option.foundingFatherFactor.shortDescription=Meningkatkan biaya pemilihan tokoh baru. model.option.arrearsFactor.name=Faktor sewa model.option.arrearsFactor.shortDescription=Meningkatkan pajak penjualan di eropa. -model.option.unitsThatUseNoBells.name=Kolonis yang tidak menggunakan lonceng -model.option.unitsThatUseNoBells.shortDescription=Jumlah penjajahan di sebuah koloni yang tidak menggunakan lonceng apapun. +model.option.unitsThatUseNoBells.name=Penjajah yang tak pakai lonceng +model.option.unitsThatUseNoBells.shortDescription=Jumlah penjajah di sebuah jajahan yang tak menggunakan lonceng apapun. model.option.tileProduction.name=Produksi petak model.option.tileProduction.shortDescription=produksi dari ubin dengan beberapa produk. model.option.tileProduction.veryLow.name=Sangat Rendah @@ -519,13 +520,13 @@ model.difficulty.cheat.name=Kecurangan AI model.option.liftBoycottCheat.name=Tarik Boikot model.option.liftBoycottCheat.shortDescription=Persentase peluang per giliran bagi pemain AI menghilangkan boikot tanpa membayar tunggakan. model.option.equipScoutCheat.name=Perlengkapan Pengintai -model.option.equipScoutCheat.shortDescription=Persentase peluang per giliran bagi pemain AI untuk memperlengkapi unit di Eropa sebagai pengintai secara gratis. +model.option.equipScoutCheat.shortDescription=Persentase peluang per giliran bagi pemain AI untuk memperlengkapi satuan di Eropa sebagai pengintai secara gratis. model.option.equipPioneerCheat.name=Perlengkapan Penjelajah -model.option.equipPioneerCheat.shortDescription=Persentase peluang per giliran bagi pemain AI untuk memperlengkapi unit di Eropa sebagai penjelajah secara gratis. -model.option.landUnitCheat.name=Mendapatkan Unit Darat -model.option.landUnitCheat.shortDescription=Persentase peluang per giliran bagi pemain AI untuk mendapatkan unit darat secara gratis di Eropa. -model.option.offensiveLandUnitCheat.name=Mendapatkan Unit Darat Ofensif -model.option.offensiveLandUnitCheat.shortDescription=Persentase peluang per giliran bagi pemain AI untuk mendapatkan unit darat ofensif secara gratis di Eropa. +model.option.equipPioneerCheat.shortDescription=Persentase peluang per giliran bagi pemain AI untuk memperlengkapi satuan di Eropa sebagai penjelajah secara gratis. +model.option.landUnitCheat.name=Dapatkan Satuan Darat +model.option.landUnitCheat.shortDescription=Persentase peluang per giliran bagi pemain AI untuk mendapatkan satuan darat secara gratis di Eropa. +model.option.offensiveLandUnitCheat.name=Dapatkan Satuan Darat Ofensif +model.option.offensiveLandUnitCheat.shortDescription=Persentase peluang per giliran bagi pemain AI untuk mendapatkan satuan darat ofensif secara gratis di Eropa. model.option.offensiveNavalUnitCheat.name=Mendapatkan Unit Laut Ofensif model.option.offensiveNavalUnitCheat.shortDescription=Persentase setiap giliran pemain AI dapat membangun unit kapal perang secara gratis di Eropa.\n( akan menurun setiap kenaikan kekuatan angkatan laut AI ) model.option.transportNavalUnitCheat.name=Dapatkan Unit Transportasi Laut @@ -545,7 +546,7 @@ model.option.settlementLimitModifier.shortDescription=Jumlah yang ditambah pada model.option.fogOfWar.name=Kabut perang model.option.fogOfWar.shortDescription=Haruskah unit musuh di luar garis pandang kita disembunyikan? model.option.explorationPoints.name=Titik penjelajahan -model.option.explorationPoints.shortDescription=Haruskah poin eksplorasi diberikan untuk semua penemuan? +model.option.explorationPoints.shortDescription=Haruskah poin penjelajahan diberikan untuk semua penemuan? model.option.amphibiousMoves.name=Gerakan amfibi model.option.amphibiousMoves.shortDescription=Izinkan unit angkatan laut untuk bergerak langsung ke pemukiman. model.option.emptyTraders.name=Unit perdagangan kosong @@ -710,9 +711,9 @@ model.option.guiMinNumberToDisplayGoods.shortDescription=Barang-barang akan ditu model.option.displayGrid.name=Tampilkan Kisi-kisi model.option.displayBorders.name=Tampilkan Perbatasan model.option.displayFogOfWar.name=Tampilkan Kabut-Perang -model.option.useOpenGL.name=Aktifkan OpenGL -model.option.useXRender.name=Aktifkan XRender -model.option.useTerrainAnimations.name=Aktifkan Animasi Medan +model.option.useOpenGL.name=Nyalakan OpenGL +model.option.useXRender.name=Nyalakan XRender +model.option.useTerrainAnimations.name=Nyalakan Animasi Medan clientOptions.gui.mapControls.ClassicMapControls.name=Klasik model.option.color.background.name=Warna Latar clientOptions.minimap.color.background.black=Hitam @@ -934,7 +935,7 @@ server.errorStartingGame=Kesalahan terjadi ketika memulai permainan. %extra% server.incompatibleVersions=Permainan tersimpan yang anda coba untuk memuatnya tidak cocok dengan FreeCol versi ini. server.invalidPlayerNations=Semua pemain harus memilih bangsa sebelum permainan dapat dimulai. server.notAllReady=Tidak semua pemain siap untuk memulai permainan! -server.wrongFreeColVersion=Klien FreeCol versi %clientVersion% yang dimana tidak cocok dengan versi server %serverVersion% +server.wrongFreeColVersion=Versi kelayan FreeCol adalah %clientVersion% yang mana tidak cocok dengan versi peladen %serverVersion% declareIndependence.announce=Koloni %oldNation% telah menyatakan kemerdekaannya dari %ruler% dan sekarang dikenal sebagai %newNation%. declareIndependence.resolution=Hari ini Kongres telah melalui pemecahan yang paling penting, yang pernah diambil di Amerika. \n\nSaya menyadari dari Kerja Keras dan Darah dan Harta, bahwa itu mengharuskan Kita untuk mempertahankan Deklarasi ini, dan mendukung dan membela negara ini. Namun melalui semua kesuraman saya dapat melihat Sinar Kejayaan dan Cahaya yang sangat menarik. Saya dapat melihat bahwa Akhir adalah lebih berharga daripada semua Tujuan. Dan bahwa Keturunan akan menang dalam Hari Transaksi, sekalipun Kita harus menyesalkan itu, yang saya percaya pada Tuhan Kita tidak akan mengalaminya. \n\nAngkatan Ekspedisi Kerajaan akan segera tiba. Hati-hati mempersiapkan pertahanan kita sementara kita menggugah sukarelawan untuk Pasukan Kontinental yang baru. colopedia.buildings.notes=Catatan @@ -993,13 +994,13 @@ infoPanel.moves=Pergerakan: loadingSavegameDialog.port=Port: loadingSavegameDialog.name=Memuat permainan yang disimpan mapSizeDialog.mapSize=Pilih ukuran peta -newPanel.getServerList=Dapatkan daftar server +newPanel.getServerList=Dapatkan daftar peladen newPanel.joinMultiPlayerGame=Bergabung dengan permainan multi pemain newPanel.nationalAdvantages=Kelebihan Negara -newPanel.publicServer=Server umum +newPanel.publicServer=Peladen umum newPanel.singlePlayerGame=Permainan pemain tunggal newPanel.startMultiplayerGame=Mulai permainan multiplayer -newPanel.startServerOnPort=Mulai server pada port +newPanel.startServerOnPort=Mulai peladen pada porta parametersDialog.determineHighSeas.maxDistanceToEdge=Jarak maksimum ke tepi playersTable.advantage=Kelebihan playersTable.availability=Ketersediaan diff --git a/data/strings/FreeColMessages_km.properties b/data/strings/FreeColMessages_km.properties index 16a616ee6c..008a9f1364 100644 --- a/data/strings/FreeColMessages_km.properties +++ b/data/strings/FreeColMessages_km.properties @@ -1,6 +1,7 @@ # Messages for Khmer (ភាសាខ្មែរ) # Exported from translatewiki.net # Author: Lovekhmer +# Author: MeahNunh # Author: T-Rithy # Author: Thearith # Author: Trychandararith @@ -767,8 +768,8 @@ colopedia.nationType.settlementNumber.high=ខ្ពស់ colopedia.nationType.settlementNumber.low=ទាប colopedia.nationType.settlementNumber=ចំនួន​អ្នកបោះទីលំនៅ​៖ colopedia.nationType.typeOfSettlements=ប្រភេទ​អ្នកបោះទីលំនៅ: -colopedia.terrain.description=ការពិពណ៌នា -colopedia.resource.description=ការពិពណ៌នា +colopedia.terrain.description=ពិពណ៌នា +colopedia.resource.description=ពិពណ៌នា colopedia.unit.description=ការពិពណ៌នា​៖ colopedia.unit.price=តម្លៃ​នៅ​អឺរ៉ុប​៖ colopedia.unit.skill=កម្រិត​ជំនាញ​៖ diff --git a/data/strings/FreeColMessages_sk.properties b/data/strings/FreeColMessages_sk.properties index b775feba2a..567b1d8091 100644 --- a/data/strings/FreeColMessages_sk.properties +++ b/data/strings/FreeColMessages_sk.properties @@ -865,10 +865,10 @@ clientOptions.gui.languageOption.autoDetectLanguage=Automaticky zistiť jazyk model.option.guiMinNumberToDisplayGoodsCount.name=Zobraziť množstvá tovaru od model.option.guiMinNumberToDisplayGoodsCount.shortDescription=Množstvo tovaru sa zobrazí keď bude väčšie alebo rovné tomuto číslu. model.option.guiMaxNumberOfGoodsImages.name=Maximálne množstvo obrázkov tovarov -model.option.guiMaxNumberOfGoodsImages.shortDescription=Zobrazenie maximálneho množstva obrázkov tovarov. +model.option.guiMaxNumberOfGoodsImages.shortDescription=Maximálne množstva obrázkov tovarov na zobrazenie. model.option.guiMinNumberToDisplayGoods.name=Skryť tovar v sklade ak ho je menej než model.option.guiMinNumberToDisplayGoods.shortDescription=Tovar bude zobrazený v kolónii ak ho bude viac alebo rovnako ako toto číslo. -model.option.alwaysCenter.name=Vždy vycentrovať na vybraté políčko +model.option.alwaysCenter.name=Vždy vycentrovať vybraté políčka model.option.alwaysCenter.shortDescription=Vždy vycentrovať na novo vybraté políčko. model.option.jumpToActiveUnit.name=Skočiť na aktívnu jednotku model.option.jumpToActiveUnit.shortDescription=Vždy vycentrovať na novo vybratú jednotku. @@ -879,44 +879,44 @@ model.option.autoScroll.shortDescription=Umožniť automatické rolovanie keď s model.option.displayCompassRose.name=Zobraziť ružicu kompasu model.option.displayCompassRose.shortDescription=Či sa má zobraziť ružica kompasu alebo nie. model.option.displayMapControls.name=Zobraziť ovládacie prvky mapy. -model.option.displayMapControls.shortDescription=Či sa majú zobraziť ovládacie prvky mapy ako predvolené nastavenie alebo nie. +model.option.displayMapControls.shortDescription=Či sa byť predvolené, že sa majú zobraziť ovládacie prvky mapy alebo nie. model.option.displayGrid.name=Zobraziť mriežku -model.option.displayGrid.shortDescription=Či sa má zobraziť mriežka ako predvolené nastavenie alebo nie. -model.option.displayBorders.name=Zobraziť okraje -model.option.displayBorders.shortDescription=Či sa majú zobraziť okraje ako predvolené nastavenie alebo nie. +model.option.displayGrid.shortDescription=Či predvolené, že sa má zobraziť mriežka alebo nie. +model.option.displayBorders.name=Zobraziť hranice +model.option.displayBorders.shortDescription=Či sa byť predvolené, že sa majú zobraziť hranice alebo nie. model.option.displayFogOfWar.name=Zobraziť vojnovú hmlu model.option.displayFogOfWar.shortDescription=Či sa má byť predvolené zobrazenie hmly vojny alebo nie. -model.option.unitLastMoveDelay.name=Oneskorenie posledného pohybu jednotky -model.option.unitLastMoveDelay.shortDescription=Či mať krátku pauzu pre posledný pohyb jednotky alebo nie. -model.option.usePixmaps.name=Použiť pixmaps na ukladanie obrázkov -model.option.usePixmaps.shortDescription=Skúste toto vypnúť ak bežný pohyb jednotiek je veľmi pomalý. +model.option.unitLastMoveDelay.name=Pauza po poslednom pohybe jednotky +model.option.unitLastMoveDelay.shortDescription=Či ma byť krátka pauza po poslednom pohybe jednotky alebo nie. +model.option.usePixmaps.name=Použiť pixmapy na ukladanie obrázkov +model.option.usePixmaps.shortDescription=Skúste toto vypnúť ak je bežný pohyb jednotiek veľmi pomalý. model.option.useOpenGL.name=Povoliť OpenGL -model.option.useopenGL.shortDescription=Skúste zapnúť toto ak GUI je veľmi pomalé a vypnúť ak je s chybami. +model.option.useopenGL.shortDescription=Skúste toto zapnúť ak je GUI veľmi pomalé a vypnúť ak je poruchové. model.option.useXRender.name=Povoliť XRender -model.option.useXRender.shortDescription=Iný prepínač, ktorý môže opraviť veľmi pomalé GUI. +model.option.useXRender.shortDescription=Ďalší prepínač, ktorý môže opraviť veľmi pomalé GUI. model.option.useTerrainAnimations.name=Povoliť animácie terénu model.option.useTerrainAnimations.shortDescription=Animuje terén ako oceány a rieky. -model.option.rememberPanelPositions.name=Zapamätať pozície panela +model.option.rememberPanelPositions.name=Zapamätať pozície panelov model.option.rememberPanelPositions.shortDescription=Zapamätať pozíciu rôznych panelov. model.option.rememberPanelSizes.name=Zapamätať si veľkosti panelov model.option.rememberPanelSizes.shortDescription=Zapamätať si veľkosť rôznych panelov. model.option.smoothRendering.name=Plynulé vykresľovanie model.option.smoothRendering.shortDescription=Umožňuje plynulé vykresľovanie mini mapy pri vzďaľovaní. -model.option.disableGrayLayer.name=Vypnúť pozadie konca ťahu +model.option.disableGrayLayer.name=Vypnúť pozadie na konci ťahu model.option.disableGrayLayer.shortDescription=Možnosť vypnúť šedé pozadie konca ťahu. -model.option.miniMapToggleFogOfWar.name=Prepnúť hmlu vojny na mini mape. -model.option.miniMapToggleFogOfWar.shortDescription=Ak je vybrané: vykreslí na mini mape hmlu vojny. -model.option.miniMapToggleBorders.name=Prepnúť okraje na mini mape -model.option.miniMapToggleBorders.shortDescription=Ak je vybrané: vykreslí na mini mape okraje. +model.option.miniMapToggleFogOfWar.name=Prepnúť vojnovú hmlu na mini mape. +model.option.miniMapToggleFogOfWar.shortDescription=Ak je vybrané: kreslí vojnovú hmlu na mini mape. +model.option.miniMapToggleBorders.name=Prepnúť hranice na mini mape +model.option.miniMapToggleBorders.shortDescription=Ak je vybrané: kreslí hranice na mini mape. model.option.mapControls.name=Ovládanie mapy -model.option.mapControls.shortDescription=Ktoré ovládacie prvky mapy zobraziť. +model.option.mapControls.shortDescription=Aký typ ovládacích prvkov mapy zobraziť. clientOptions.gui.mapControls.CornerMapControls.name=Rohy clientOptions.gui.mapControls.CornerMapControls.shortDescription=Ovládanie mapy zaberá rohy a spodnú hranu. clientOptions.gui.mapControls.ClassicMapControls.name=Klasické clientOptions.gui.mapControls.ClassicMapControls.shortDescription=Ovládanie mapy zaberá pravú hranu. model.option.color.background.name=Farba pozadia -model.option.color.background.shortDescription=Keď je mini mapa úplne vzdialená, táto farba obklopuje mapu a hmlu vojny. -clientOptions.minimap.color.background.black=Čierne +model.option.color.background.shortDescription=Keď je mini mapa úplne odzoomovaná, táto farba obklopuje mapu a vojnovú hmlu. +clientOptions.minimap.color.background.black=Čierna clientOptions.minimap.color.background.gray.dark.very=Veľmi tmavosivá clientOptions.minimap.color.background.gray.dark=Tmavosivá clientOptions.minimap.color.background.gray=Sivá @@ -925,29 +925,29 @@ clientOptions.minimap.color.background.gray.light.very=Veľmi svetlosivá clientOptions.minimap.color.background.blue.light=Svetlomodrá model.option.displayTileText.name=Zobrazenie textu políčka model.option.displayTileText.shortDescription=Aký text sa zobrazí na políčku. -clientOptions.gui.displayTileText.empty.name=Prázdny +clientOptions.gui.displayTileText.empty.name=Prázdne clientOptions.gui.displayTileText.empty.shortDescription=Nezobrazovať text clientOptions.gui.displayTileText.names.name=Názov políčok clientOptions.gui.displayTileText.names.shortDescription=Zobraziť typ terénu clientOptions.gui.displayTileText.owners.name=Majitelia políčka -clientOptions.gui.displayTileText.owners.shortDescription=Zobraziť národnosť majiteľa políčka +clientOptions.gui.displayTileText.owners.shortDescription=Zobraziť národnosť majiteľa políčka ak existuje clientOptions.gui.displayTileText.regions.name=Región políčka clientOptions.gui.displayTileText.regions.shortDescription=Zobraziť do ktorého regióna políčko patrí -model.option.displayColonyLabels.name=Štítky kolónie -model.option.displayColonyLabels.shortDescription=Štýl štítku kolónie. +model.option.displayColonyLabels.name=Popisky kolónií +model.option.displayColonyLabels.shortDescription=Štýl popiskov kolónií. clientOptions.gui.displayColonyLabels.none.name=Žiadne -clientOptions.gui.displayColonyLabels.none.shortDescription=Nezobrazovať štítky +clientOptions.gui.displayColonyLabels.none.shortDescription=Nezobrazovať popisky kolónií clientOptions.gui.displayColonyLabels.classic.name=Klasické clientOptions.gui.displayColonyLabels.classic.shortDescription=Označiť kolónie menom a veľkosťou clientOptions.gui.displayColonyLabels.modern.name=Moderné -clientOptions.gui.displayColonyLabels.modern.shortDescription=Kompletný štítok kolónie vrátane bonusu výroby a prebiehajúcich stavieb +clientOptions.gui.displayColonyLabels.modern.shortDescription=Komplexný popisok kolónie vrátane produkčných bonusov a prebiehajúcich stavieb model.option.colonyComparator.name=Zoradiť kolónie podľa model.option.colonyComparator.shortDescription=Určuje ako sa kolónie zoradia. -clientOptions.gui.colonyComparator.byName.name=Názov +clientOptions.gui.colonyComparator.byName.name=Názvu clientOptions.gui.colonyComparator.byName.shortDescription=Zoradiť abecedne podľa názvu -clientOptions.gui.colonyComparator.byAge.name=Vek -clientOptions.gui.colonyComparator.byAge.shortDescription=Zoradiť podľa vybudovania -clientOptions.gui.colonyComparator.byPosition.name=Pozícia +clientOptions.gui.colonyComparator.byAge.name=Veku +clientOptions.gui.colonyComparator.byAge.shortDescription=Zoradiť podľa poradia vybudovania +clientOptions.gui.colonyComparator.byPosition.name=Pozície clientOptions.gui.colonyComparator.byPosition.shortDescription=Zoradiť podľa geografickej polohy clientOptions.gui.colonyComparator.bySize.name=Veľkosť clientOptions.gui.colonyComparator.bySize.shortDescription=Zoradiť od najväčšej po najmenšiu @@ -962,13 +962,13 @@ clientOptions.gui.graphicsQuality.low=Nízka clientOptions.gui.graphicsQuality.normal=Normálna clientOptions.gui.graphicsQuality.high=Vysoká clientOptions.gui.graphicsQuality.highest=Najvyššia -model.option.moveAnimationSpeed.name=Rýchlosť animácie priateľských jednotiek -model.option.moveAnimationSpeed.shortDescription=Zmení rýchlosť animácie pohybu priateľských jednotiek. +model.option.moveAnimationSpeed.name=Rýchlosť animácie pohybu našich jednotiek +model.option.moveAnimationSpeed.shortDescription=Zmení rýchlosť animácie pohybu našich jednotiek. clientOptions.gui.moveAnimationSpeed.off=Vypnutá clientOptions.gui.moveAnimationSpeed.slow=Pomalá clientOptions.gui.moveAnimationSpeed.normal=Normálna clientOptions.gui.moveAnimationSpeed.fast=Rýchla -model.option.enemyMoveAnimationSpeed.name=Rýchlosť animácie nepriateľských jednotiek +model.option.enemyMoveAnimationSpeed.name=Rýchlosť animácie pohybu nepriateľských jednotiek model.option.enemyMoveAnimationSpeed.shortDescription=Zmení rýchlosť animácie pohybu nepriateľských jednotiek. clientOptions.gui.enemyMoveAnimationSpeed.off=Vypnutá clientOptions.gui.enemyMoveAnimationSpeed.slow=Pomalá @@ -981,10 +981,10 @@ clientOptions.gui.friendlyMoveAnimationSpeed.slow=Pomalá clientOptions.gui.friendlyMoveAnimationSpeed.normal=Normálna clientOptions.gui.friendlyMoveAnimationSpeed.fast=Rýchla clientOptions.messages.name=Správy -clientOptions.messages.shortDescription=Možnosti pre zapnutie/vypnutie správ. +clientOptions.messages.shortDescription=Možnosť zapnutia/vypnutia správ. model.option.guiMessagesGroupBy.name=Triediť správy podľa -model.option.guiMessagesGroupBy.shortDescription=Určuje, ako by mali byť správy vytriedené. -clientOptions.messages.guiMessagesGroupBy.nothing.name=Nič +model.option.guiMessagesGroupBy.shortDescription=Určuje, ako majú byť správy triedené. +clientOptions.messages.guiMessagesGroupBy.nothing.name=Nijako clientOptions.messages.guiMessagesGroupBy.nothing.shortDescription=Správy sú netriedené clientOptions.messages.guiMessagesGroupBy.type.name=Typ clientOptions.messages.guiMessagesGroupBy.type.shortDescription=Správy sú triedené podľa typu @@ -992,7 +992,7 @@ clientOptions.messages.guiMessagesGroupBy.source.name=Zdroj clientOptions.messages.guiMessagesGroupBy.source.shortDescription=Správy sú triedené podľa toho čo ich vytvorilo model.option.guiShowBuildingCompleted.name=Správy o dokončení stavby model.option.guiShowBuildingCompleted.shortDescription=Určuje, či zobrazovať správy o dokončení budovy na začiatku každého ťahu. -model.option.guiShowCombatResult.name=Bojovné správy +model.option.guiShowCombatResult.name=Správy o bojoch model.option.guiShowCombatResult.shortDescription=Určuje, či na začiatku každého ťahu zobrazovať výsledky z bojov. model.option.guiShowDemands.name=Požiadavky domorodcov model.option.guiShowDemands.shortDescription=Určuje, či zobrazovať správy o požiadavkách domorodcov na začiatku každého ťahu. @@ -1002,8 +1002,8 @@ model.option.guiShowForeignDiplomacy.name=Správy o zahraničnej diplomacii model.option.guiShowForeignDiplomacy.shortDescription=Určuje, či zobrazovať správy o zahraničnej diplomacii. model.option.guiShowGifts.name=Dary od domorodcov model.option.guiShowGifts.shortDescription=Určuje, či zobrazovať správy o daroch od domorodcov na začiatku každého ťahu. -model.option.guiShowGoodsMovement.name=Pohyb tovaru -model.option.guiShowGoodsMovement.shortDescription=Určuje, či zobrazovať podrobné správy o pohybe tovaru. +model.option.guiShowGoodsMovement.name=Pohyb tovarov +model.option.guiShowGoodsMovement.shortDescription=Určuje, či zobrazovať podrobné správy o pohybe tovarov. model.option.guiShowGovernmentEfficiency.name=Správy o výkonnosti vlády model.option.guiShowGovernmentEfficiency.shortDescription=Určuje, či zobrazovať správy o výkonnosti vlády na začiatku každého ťahu. model.option.guiShowMarketPrices.name=Správy o trhových cenách @@ -1012,36 +1012,36 @@ model.option.guiShowMissingGoods.name=Chýbajúci tovar model.option.guiShowMissingGoods.shortDescription=Určuje, či zobrazovať správy o chýbajúcom tovare na začiatku každého ťahu. model.option.guiShowSonsOfLiberty.name=Správy o Synoch slobody model.option.guiShowSonsOfLiberty.shortDescription=Určuje, či zobrazovať správy o Synoch slobody na začiatku každého ťahu. -model.option.guiShowTutorial.name=Správy o výučbe -model.option.guiShowTutorial.shortDescription=Zobrazovať správy o výučbe +model.option.guiShowTutorial.name=Správy tutoriálu +model.option.guiShowTutorial.shortDescription=Zobrazovať správy tutoriálu model.option.guiShowUnitAdded.name=Správy o nových kolonistoch model.option.guiShowUnitAdded.shortDescription=Určuje, či zobrazovať správy o nových kolonistoch na začiatku každého ťahu. model.option.guiShowUnitArrived.name=Správy o príchode jednotky -model.option.guiShowUnitArrived.shortDescription=Určuje, či zobrazovať správy o jednotkách prichádzajúcich do Európy. -model.option.guiShowUnitDemoted.name=Správy o degradácii jednotky -model.option.guiShowUnitDemoted.shortDescription=Určuje, či zobrazovať správy o degradácii jednotky. -model.option.guiShowUnitImproved.name=Správy o zlepšení jednotky +model.option.guiShowUnitArrived.shortDescription=Určuje, či zobrazovať správy o jednotkách k dispozícii v Európe. +model.option.guiShowUnitDemoted.name=Správy o degradácii jednotiek +model.option.guiShowUnitDemoted.shortDescription=Určuje, či zobrazovať správy o degradácii jednotiek +model.option.guiShowUnitImproved.name=Správy o zlepšení jednotiek model.option.guiShowUnitImproved.shortDescription=Určuje, či zobrazovať správy o zlepšení jednotky na začiatku každého ťahu. -model.option.guiShowUnitLost.name=Správy o strate jednotky -model.option.guiShowUnitLost.shortDescription=Určuje, či zobrazovať správy o strate jednotky. +model.option.guiShowUnitLost.name=Správy o strate jednotiek +model.option.guiShowUnitLost.shortDescription=Určuje, či zobrazovať správy o strate jednotiek. model.option.guiShowUnitRepaired.name=Správy o opravách jednotiek -model.option.guiShowUnitRepaired.shortDescription=Určuje, či zobrazovať alebo nezobrazovať správy o oprave jednotiek. +model.option.guiShowUnitRepaired.shortDescription=Určuje, či zobrazovať správy o oprave jednotiek. model.option.guiShowWarehouseCapacity.name=Správy o kapacite skladu model.option.guiShowWarehouseCapacity.shortDescription=Určuje, či zobrazovať správy o kapacite skladu na začiatku každého ťahu. model.option.guiShowWarning.name=Varovné správy model.option.guiShowWarning.shortDescription=Určuje, či zobrazovať rôzne varovné správy. -model.option.guiShowColonyWarnings.name=Upozornenia kolónie -model.option.guiShowColonyWarnings.shortDescription=Určuje, či zobrazovať upozornenia kolónie. +model.option.guiShowColonyWarnings.name=Upozornenia o polohe kolónie +model.option.guiShowColonyWarnings.shortDescription=Určuje, či zobrazovať upozornenia o vhodnosti pozície kolónie. model.option.guiShowPreCombat.name=Predbojová analýza model.option.guiShowPreCombat.shortDescription=Určuje, či zobrazovať predbojovú analýzu. model.option.guiShowNotBestTile.name=Nie najlepšie políčko -model.option.guiShowNotBestTile.shortDescription=Určuje, či zobrazovať, že jednotky nepracujú na najlepšom políčku. +model.option.guiShowNotBestTile.shortDescription=Určuje, či zobrazovať upozornenie, že jednotky nepracujú na najlepšom dostupnom políčku. model.option.guiShowRegionNaming.name=Pomenovanie regiónov model.option.guiShowRegionNaming.shortDescription=Zobrazovať dialóg pomenovania regiónov pri prieskume. model.option.colonyReport.name=Hlásenie kolónie model.option.colonyReport.shortDescription=Súhrn činnosti v každej kolóne. clientOptions.messages.colonyReport.classic.name=Klasické -clientOptions.messages.colonyReport.classic.shortDescription=Podrobné správy o kolónii. +clientOptions.messages.colonyReport.classic.shortDescription=Podrobné správy, aj s obrázkami, o stave kolónií. clientOptions.messages.colonyReport.compact.name=Kompaktné clientOptions.messages.colonyReport.compact.shortDescription=Kompaktné správy o kolónii sa snažia zobraziť čo najviac o kolónii v jedinom riadku. model.option.labourReport.name=Pracovné hlásenie @@ -1052,38 +1052,38 @@ clientOptions.messages.labourReport.compact.name=Kompaktná clientOptions.messages.labourReport.compact.shortDescription=Kompaktnejšia verzia klasickej správy. clientOptions.savegames.name=Uložené hry clientOptions.savegames.shortDescription=Uložené hry -model.option.showSavegameSettings.name=Uložiť dialógové okno hry +model.option.showSavegameSettings.name=Dialógové okno uloženej hry model.option.showSavegameSettings.shortDescription=Zobraziť dialógové okno pre nastavenie možností servera pri načítavaní uloženej hry. clientOptions.savegames.showSavegameSettings.never.name=Nikdy clientOptions.savegames.showSavegameSettings.never.shortDescription=Nikdy nezobrazovať dialógové okno nastavení možností servera -clientOptions.savegames.showSavegameSettings.multiplayer.name=Hra pre viacerých hráčov -clientOptions.savegames.showSavegameSettings.multiplayer.shortDescription=Zobraziť dialógové okno možností servera len pre uložené hry pre viacerých hráčov +clientOptions.savegames.showSavegameSettings.multiplayer.name=Hra viacerých hráčov +clientOptions.savegames.showSavegameSettings.multiplayer.shortDescription=Zobraziť dialógové okno možností servera len pre uložené pri hre viacerých hráčov clientOptions.savegames.showSavegameSettings.always.name=Vždy clientOptions.savegames.showSavegameSettings.always.shortDescription=Vždy zobraziť dialógové okno možností servera model.option.autosavePeriod.name=Automatické ukladanie každých x ťahov model.option.autosavePeriod.shortDescription=Lehota na automatické uloženie hry a použitie tlačidla 0 na vypnutie tejto funkcie. model.option.autosaveValidity.name=Vymazať automaticky uložené hry po x dňoch model.option.autosaveValidity.shortDescription=Čas platnosti súboru uloženého automaticky od jeho vytvorenia v dňoch. Nastavte 0 na ignorovanie tejto podmienky. -model.option.autosaveDelete.name=Vymazať súbory uložené automatiky -model.option.autosaveDelete.shortDescription=Vymazať staré súbory uložené automaticky pri spustení novej hry. +model.option.autosaveDelete.name=Vymazať súbory uložené automaticky +model.option.autosaveDelete.shortDescription=Vymazať staré súbory uložené automaticky pri spustení novej hry. model.option.confirmSaveOverwrite.name=Potvrdiť prepísanie uloženia -model.option.confirmSaveOverwrite.shortDescription=Možnosť potvrdiť prepísanie už existujúceho súboru. +model.option.confirmSaveOverwrite.shortDescription=Možnosť potvrdiť prepísanie existujúcich súborov. model.option.autoSavePrefix.name=Predpona súborov uložených automaticky -model.option.autoSavePrefix.shortDescription=Predpona pre súbory uložené automaticky. +model.option.autoSavePrefix.shortDescription=Predpona názvov súborov uložených automaticky. model.option.lastTurnName.name=Názov súboru posledného ťahu -model.option.lastTurnName.shortDescription=Označenie mena uloženého súboru s posledným ťahom. +model.option.lastTurnName.shortDescription=Základ mena uloženého súboru s posledným ťahom. model.option.beforeLastTurnName.name=Názov súboru predposledného ťahu -model.option.beforeLastTurnName.shortDescription=Označenie mena uloženého súboru s predposledným ťahom. -clientOptions.warehouse.name=Nastavenie skladu -clientOptions.warehouse.shortDescription=Zmeniť predvolené nastavenia pre sklady a vlastné domy. -model.option.customStock.name=Predvolené zásoby vlastného domu -model.option.customStock.shortDescription=Zásoby, ktoré by mal vlastný dom udržiavať pri predaji tovaru. -model.option.lowLevel.name=Varovanie nízkej úrovne -model.option.lowLevel.shortDescription=Vytvoriť varovanie keď zásoby klesnú pod túto úroveň. -model.option.highLevel.name=Varovanie vysokej úrovne -model.option.highLevel.shortDescription=Vytvoriť varovanie keď zásoby presiahnu túto úroveň. -model.option.stockAccountsForProduction.name=Stav zásob pre produkciu -model.option.stockAccountsForProduction.shortDescription=Obchodné cesty kontrolujú množstvo tovarov vrátane predpokladanej výroby aby určili, či majú navštíviť zastávku. +model.option.beforeLastTurnName.shortDescription=Základ mena uloženého súboru s predposledným ťahom. +clientOptions.warehouse.name=Nastavenia skladu +clientOptions.warehouse.shortDescription=Zmeniť predvolené nastavenia pre sklady a colnice. +model.option.customStock.name=Predvolené zásoby colnice +model.option.customStock.shortDescription=Zásoby, ktoré by mala colnica udržiavať pri predaji tovaru. +model.option.lowLevel.name=Varovanie nízkeho stavu +model.option.lowLevel.shortDescription=Upozorniť, keď zásoby klesnú pod túto úroveň. +model.option.highLevel.name=Varovanie vysokého stavu +model.option.highLevel.shortDescription=Upozorniť, keď zásoby presiahnu túto úroveň. +model.option.stockAccountsForProduction.name=Zásoby surovín pre produkciu +model.option.stockAccountsForProduction.shortDescription=Obchodné cesty zisťujú množstvo tovarov vrátane predpokladanej výroby aby určili, či majú navštíviť zastávku. clientOptions.audio.name=Zvuk clientOptions.audio.shortDescription=Nastavenia zvuku clientOptions.audio.audioMixer.automatic=Automatická detekcia audio výstupu @@ -1095,8 +1095,8 @@ model.option.audioVolume.name=Hlasitosť zvuku model.option.audioVolume.shortDescription=Hlasitosť zvuku model.option.soundEffectsVolume.name=Hlasitosť zvukových efektov model.option.soundEffectsVolume.shortDescription=Hlasitosť zvukových efektov -model.option.audioAlerts.name=Zvukové upozornenia -model.option.audioAlerts.shortDescription=Zapnúť zvukové upozornenia +model.option.audioAlerts.name=Zvukové výstrahy +model.option.audioAlerts.shortDescription=Zapnúť zvukové výstrahy clientOptions.other.name=Iné clientOptions.other.shortDescription=Možnosti, ktoré sa nehodia do ostatných kategórii model.option.autoloadEmigrants.name=Automaticky nalodiť prisťahovalcov pri plavbe do Ameriky @@ -1107,37 +1107,37 @@ model.option.autoEndTurn.name=Automaticky ukončiť ťah model.option.autoEndTurn.shortDescription=Automaticky ukončí ťah keď už nie sú jednotky, ktoré by sa mohli hýbať. model.option.showEndTurnDialog.name=Dialógové okno pri konci ťahu model.option.showEndTurnDialog.shortDescription=Ukázať dialógové okno pri konci ťahu ak ešte sú jednotky, ktoré by sa mohli hýbať. -model.option.indianDemandResponse.name=Odpovedať na požiadavky indiánov -model.option.indianDemandResponse.shortDescription=Čo urobiť keď domorodci žiadajú tovar. -clientOptions.other.indianDemandResponse.ask.name=Spýtať sa -clientOptions.other.indianDemandResponse.ask.shortDescription=Spýtať sa, čo robiť +model.option.indianDemandResponse.name=Odpoveď na požiadavky indiánov +model.option.indianDemandResponse.shortDescription=Čo urobiť keď domorodci žiadajú alebo požadujú tovar. +clientOptions.other.indianDemandResponse.ask.name=Opýtať sa +clientOptions.other.indianDemandResponse.ask.shortDescription=Opýtať sa, čo robiť clientOptions.other.indianDemandResponse.accept.name=Prijať clientOptions.other.indianDemandResponse.accept.shortDescription=Prijať všetky požiadavky domorodcov clientOptions.other.indianDemandResponse.reject.name=Odmietnuť clientOptions.other.indianDemandResponse.reject.shortDescription=Odmietnuť všetky požiadavky domorodcov -model.option.unloadOverflowResponse.name=Vyhodiť prebytok +model.option.unloadOverflowResponse.name=Vyložiť prebytok model.option.unloadOverflowResponse.shortDescription=Čo urobiť keď sa pri vykladaní tovaru z lode preplní sklad. -clientOptions.other.unloadOverflowResponse.ask.name=Spýtať sa -clientOptions.other.unloadOverflowResponse.ask.shortDescription=Spýtať sa, čo robiť +clientOptions.other.unloadOverflowResponse.ask.name=Opýtať sa +clientOptions.other.unloadOverflowResponse.ask.shortDescription=opýtať sa vás, čo robiť clientOptions.other.unloadOverflowResponse.never.name=Nikdy clientOptions.other.unloadOverflowResponse.never.shortDescription=Nikdy nevykladať tovar, ktorý môže preplniť sklad. clientOptions.other.unloadOverflowResponse.always.name=Vždy clientOptions.other.unloadOverflowResponse.always.shortDescription=Vždy vyložiť tovar, aj keď preplní sklad. -clientOptions.mods.name=Mody +clientOptions.mods.name=Módy clientOptions.mods.shortDescription=Nastavenia pre umožnenie herných modifikácií. -clientOptions.mods.userMods.name=Užívateľské úpravy -clientOptions.mods.userMods.shortDescription=Možnosti umožňujúce úpravy hry. +clientOptions.mods.userMods.name=Užívateľské módy +clientOptions.mods.userMods.shortDescription=Voľba povoľujúca herné modifikácie. clientOptions.etc.name=Atď -model.ability.addTaxToBells.name=Pridať daň na zvony +model.ability.addTaxToBells.name=Pridať daň k zvonom model.ability.addTaxToBells.shortDescription=Sadzba dane sa chová ako bonus výroby zvonov model.ability.alwaysOfferedPeace.name=Vždy ponúkaný mier model.ability.alwaysOfferedPeace.shortDescrption=Európske národy sú vždy pripravené ponúknuť mier model.ability.ambushBonus.name=Bonus za prepadnutie model.ability.ambushBonus.shortDescription=Bonus za prepadnutie na otvorenom priestranstve. -model.ability.ambushPenalty.name=Znevýhodnenie za prepad -model.ability.ambushPenalty.shortDescription=Tento národ bol prepadnutý a je kvôli tomu znevýhodnený. -model.ability.ambushTerrain.name=Obkľúčiť terén -model.ability.ambushTerrain.shortDescription=Tento terén umožňuje obkľúčenie +model.ability.ambushPenalty.name=Penalizácia za prepad +model.ability.ambushPenalty.shortDescription=Tento národ utrpí penalizáciu za prepad. +model.ability.ambushTerrain.name=Terén pre prepad +model.ability.ambushTerrain.shortDescription=Tento terén umožňuje prepad model.ability.armed.name=Ozbrojený model.ability.armed.shortDescription=Jednotky, ktoré sú ozbrojené model.ability.autoProduction.name=Automatická výroba @@ -1146,7 +1146,7 @@ model.ability.automaticEquipment.name=Automatické vybavenie model.ability.automaticEquipment.shortDescription=Jednotky sa môžu automaticky vyzbrojiť na obranu osady model.ability.automaticPromotion.name=Automatické povýšenie model.ability.automaticPromotion.shortDescription=Jednotky sú automaticky povýšené ak vyhrajú boj -model.ability.avoidExcessProduction.name=Vyhnúť sa prebytočnej výrobe +model.ability.avoidExcessProduction.name=Vyhnúť sa nadmernej produkcii model.ability.avoidExcessProduction.shortDescription=Nikdy nevyrobiť viac tovaru než sa dá uskladniť. model.ability.betterForeignAffairsReport.name=Vylepšené správy zahraničných vecí model.ability.betterForeignAffairsReport.shortDescription=Hlásenie o zahraničných veciach obsahuje informácie naviac @@ -1159,9 +1159,9 @@ model.ability.bornInColony.shortDescription=Jednotky narodené v kolónii model.ability.bornInIndianSettlement.name=Narodený v domorodej osade model.ability.bornInIndianSettlement.shortDescription=Jednotky narodené v domorodej osade model.ability.build.name=Stavať -model.ability.build.shortDescription=Schopnosť budovať jednotky, zariadenie alebo budovy, niekedy zvláštneho typu -model.ability.buildCustomHouse.name=Stavať vlastný dom -model.ability.buildCustomHouse.shortDescription=Schopnosť postaviť vlastný dom +model.ability.build.shortDescription=Schopnosť budovať jednotky, vybavenie alebo budovy, niekedy určitého typu +model.ability.buildCustomHouse.name=Stavať colnicu +model.ability.buildCustomHouse.shortDescription=Schopnosť postaviť colnicu model.ability.buildFactory.name=Stavať továrne model.ability.buildFactory.shortDescription=Schopnosť stavať továrenskú úroveň budov model.ability.canBeCaptured.name=Dá sa zajať @@ -1172,34 +1172,34 @@ model.ability.canRecruitUnit.name=Povolať jednotky model.ability.canRecruitUnit.shortDescription=Tento národ má schopnosť povolávať jednotky. model.ability.captureEquipment.name=Môže zabaviť vybavenie model.ability.captureEquipment.shortDescription=Schopnosť ukoristiť vybavenie -model.ability.captureGoods.name=Zajať tovať -model.ability.captureGoods.shortDescription=Táto jednotka je schopná zajať tovar. +model.ability.captureGoods.name=Zhabať tovať +model.ability.captureGoods.shortDescription=Táto jednotka je schopná zhabať tovar. model.ability.captureUnits.name=Môže zajať jednotky model.ability.captureUnits.shortDescription=Schopnosť zajať jednotky v boji model.ability.carryGoods.name=Prepravovať tovar model.ability.carryGoods.shortDescription=Táto jednotka má schopnosť prepravovať tovar. model.ability.carryTreasure.name=Môže prevážať poklad -model.ability.carryTreasure.shortDescription=Táto jednotka môže niesť poklad -model.ability.carryUnits.name=Prepravné jednotky +model.ability.carryTreasure.shortDescription=Táto jednotka môže prevážať poklad +model.ability.carryUnits.name=Prepravovať jednotky model.ability.carryUnits.shortDescription=Táto jednotka má schopnosť prepravovať iné jednotky. model.ability.coastalOnly.name=Len pobrežné model.ability.coastalOnly.shortDescription=Obmedziť niektoré stavby len na pobrežné kolónie -model.ability.customHouseTradesWithForeignCountries.name=Zahraničný predaj vlastným domom -model.ability.customHouseTradesWithForeignCountries.shortDescription=Predávať zahraničným krajinám prostredníctvom vlastného domu +model.ability.customHouseTradesWithForeignCountries.name=Zahraničný ochod prostredníctvom colnice +model.ability.customHouseTradesWithForeignCountries.shortDescription=Predávať zahraničným krajinám prostredníctvom colnice model.ability.demandTribute.name=Požadovať poplatok model.ability.demandTribute.shortDescription=Táto jednotka môže požadovať poplatok od nepriateľskej osady model.ability.demoteOnAllEquipLost.name=Degradovať po strate vybavenia model.ability.demoteOnAllEquipLost.shortDescription=Táto jednotka bude degradovaná ak stratí všetko svoje vybavenie -model.ability.denounceHeresy.name=Udať z kacírstva -model.ability.denounceHeresy.shortDescription=Jednotky, ktoré môžu udať nepriateľskú cirkevnú misiu z kacírstva +model.ability.denounceHeresy.name=Obviniť z kacírstva +model.ability.denounceHeresy.shortDescription=Jednotky, ktoré môžu obviniť nepriateľskú cirkevnú misiu z kacírstva model.ability.disposeOnAllEquipLost.name=Zničiť pri strate vybavenia model.ability.disposeOnAllEquipLost.shortDescription=Táto jednotka je zničená ak stratí všetko svoje vybavenie model.ability.disposeOnCombatLoss.name=Zničiť po prehratom boji model.ability.disposeOnCombatLoss.shortDescription=Táto jednotka bude zničená ak prehrá boj model.ability.dressMissionary.name=Vyslať misionára -model.ability.dressMissionary.shortDescription=Možnosť vyslať neodbornú jednotku ako misionára. +model.ability.dressMissionary.shortDescription=Spraviť z jednotky (neskúseného) misionára model.ability.electFoundingFather.name=Voliť zakladateľov -model.ability.electFoundingFather.shortDescription=Tento národ má schopnosť voliť zakladateľov. +model.ability.electFoundingFather.shortDescription=Tento národ má schopnosť voliť otcov zakladateľov. model.ability.establishMission.name=Založiť cirkevnú misiu model.ability.establishMission.shortDescription=Schopnosť založiť cirkevnú misiu model.ability.evadeAttack.name=Vyhnúť sa útoku @@ -1210,10 +1210,10 @@ model.ability.expertPioneer.name=Schopnosť fungovať ako expert priekopník model.ability.expertPioneer.shortDescription=Táto jednotka môže pracovať ako expert priekopník model.ability.expertScout.name=Schopnosť fungovať ako expert prieskumník model.ability.expertScout.shortDescription=Táto jednotka môže fungovať ako expert prieskumník -model.ability.expertSoldier.name=Schopnosť fungovať ako expert vojak +model.ability.expertSoldier.name=Schopnosť fungovať ako vojak veterán model.ability.expertSoldier.shortDescription=Táto jednotka môže fungovať ako vojak veterán model.ability.expertsUseConnections.name=Odborníci používajú známosti -model.ability.expertsUseConnections.shortDescription=Odborné jednotky získavajú suroviny aj keď už žiadne nie sú k dispozícii. +model.ability.expertsUseConnections.shortDescription=Odborné jednotky dokážu získavať suroviny aj keď už žiadne nie sú k dispozícii. model.ability.export.name=Vývoz tovaru model.ability.export.shortDescription=Možnosť vyviesť tovar priamo do Európy. model.ability.foundColony.name=Založiť kolóniu @@ -1223,7 +1223,7 @@ model.ability.foundInLostCity.shortDescription=Typ jednotky nájdený v stranen model.ability.foundsColonies.name=Zakladať kolónie model.ability.foundsColonies.shortDescription=Tento národ má schopnosť zakladať nové kolónie. model.ability.hasPort.name=Prístup k moru -model.ability.hasPort.shortDescription=Toto umiestnenie má priamy alebo nepriamy prístup k moru +model.ability.hasPort.shortDescription=Toto lokácia má priamy alebo nepriamy prístup k moru model.ability.ignoreEuropeanWars.name=Ignorovať európske vojny model.ability.ignoreEuropeanWars.shortDescription=Vyhlásenie vojny v Európe už tento národ neovplyvňuje model.ability.improveTerain.name=Vylepšiť terén @@ -1236,49 +1236,49 @@ model.ability.independentNation.name=Nezávislý národ model.ability.independentNation.shortDescription=Nezávislý národ model.ability.mercenaryUnit.name=Žoldnierska jednotka model.ability.mercenaryUnit.shortDescription=Táto jednotka sa nachádza v žoldnierskych silách -model.ability.mounted.name=Na koni +model.ability.mounted.name=Jazda model.ability.mounted.shortDescription=Jednotky na koňoch model.ability.moveToEurope.name=Presunúť do Európy model.ability.moveToEurope.shortDescription=Toto políčko umožňuje presunúť jednotky to Európy -model.ability.multipleAttacks.name=Viacero útokov -model.ability.multipleAttacks.shortDescription=Táto jednotka môže viac krát zaútočiť +model.ability.multipleAttacks.name=Viacnásobný útok +model.ability.multipleAttacks.shortDescription=Táto jednotka môže zaútočiť viackrát model.ability.native.name=Indián -model.ability.native.shortDescription=Rodený Američan +model.ability.native.shortDescription=Domorodý Američan model.ability.navalUnit.name=Námorná jednotka model.ability.navalUnit.shortDescription=Toto je námorná jednotka. model.ability.negotiate.name=Vyjednávať model.ability.negotiate.shortDescription=Jednotky, ktoré môžu vyjednávať so starostom kolónie -model.ability.person.name=Človek -model.ability.person.shortDescription=Táto jednotka je človek +model.ability.person.name=Osoba +model.ability.person.shortDescription=Táto jednotka je osoba model.ability.pillageUnprotectedColony.name=Rabovanie model.ability.pillageUnprotectedColony.shortDescription=Môže rabovať nechránené kolónie model.ability.piracy.name=Pirátstvo model.ability.piracy.shortDescription=Toto je pirátska jednotka model.ability.plunderNatives.name=Rabovanie domorodcov -model.ability.plunderNatives.shortDescription=Zvýšiť množstvo koristi po zničení domorodej osady +model.ability.plunderNatives.shortDescription=Zvýšuje množstvo koristi po zničení domorodej osady model.ability.produceInWater.name=Vyrábať na vode model.ability.produceInWater.shortDescription=Jednotky môžu používať políčka s vodou tak isto ako pozemné políčka model.ability.refUnit.name=Jednotka KES -model.ability.refUnit.shortDescription=Toto je jednotka KES +model.ability.refUnit.shortDescription=Táto jednotka patrí ku KES model.ability.repairUnits.name=Oprava jednotiek -model.ability.repairUnits.shortDescription=Môžno opraviť niektoré poškodené jednotky +model.ability.repairUnits.shortDescription=Môže opraviť niektoré poškodené jednotky model.ability.royalExpeditionaryForce.name=Kráľovské expedičné sily model.ability.royalExpeditionaryForce.shortDescription=Národ Kráľovských expedičných síl model.ability.rumoursAlwaysPositive.name=Povesti sú vždy pozitívne model.ability.rumoursAlwaysPositive.shortDescription=Preskúmanie povestí má vždy pozitívny výsledok model.ability.seeAllColonies.name=Vidieť všetky kolónie -model.ability.seeAllColonies.shortDescription=Možno vidieť všetky zahraničné kolónie -model.ability.selectRecruit.name=Vybrať regrútov +model.ability.seeAllColonies.shortDescription=Môže vidieť všetky cudzie kolónie +model.ability.selectRecruit.name=Vybrať regrúta model.ability.selectRecruit.shortDescription=Schopnosť vybrať regrútov -model.ability.speakWithChief.name=Rozprávať sa s náčelníkom -model.ability.speakWithChief.shortDescription=Táto jednotka sa môže rozprávať s náčelníkom domorodej osady -model.ability.spyOnColony.name=Špehovanie kolónií -model.ability.spyOnColony.shortDescription=Táto jednotka môže špehovať zahraničné kolónie +model.ability.speakWithChief.name=Hovoriť s náčelníkom +model.ability.speakWithChief.shortDescription=Táto jednotka môže hovoriť s náčelníkom domorodej osady +model.ability.spyOnColony.name=Špionáž v kolóniach +model.ability.spyOnColony.shortDescription=Táto jednotka môže vykonávať špionáž v cudzích kolóniach model.ability.supportUnit.name=Podporná jednotka -model.ability.supportUnit.shortDescription=Táto jednotka sa nachádza v podporných silách +model.ability.supportUnit.shortDescription=Táto jednotka patrí k podporným silám model.ability.teach.name=Vyučovať zručnosti model.ability.teach.shortDescription=Odborníci môžu učiť ostatných svojim schopnostiam -model.ability.tradeWithForeignColonies.name=Obchodovanie so zahraničnými kolóniami +model.ability.tradeWithForeignColonies.name=Obchodovanie s cudzími kolóniami model.ability.tradeWithForeignColonies.shortDescription=Schopnosť obchodovania so zahraničnými kolóniami model.ability.undead.name=Nemŕtvy model.ability.undead.shortDescription=Jednotka zo záhrobia @@ -1288,13 +1288,13 @@ model.modifier.artilleryInTheOpen.name=Delostrelectvo na otvorenom priestranstve model.modifier.attackBonus.name=Útočný bonus model.modifier.bigMovementPenalty.name=Veľká penalizácia pohybu model.modifier.bombardBonus.name=Bombardovací bonus -model.modifier.bombardBonus.shortDescription=Jednotky tohoto národa získavajú bonus z bombardovania. +model.modifier.bombardBonus.shortDescription=Jednotky tohoto národa profitujú z Bombardovacieho bonusu. model.modifier.breedingDivisor.name=Veľkosť stád model.modifier.breedingDivisor.shortDescription=Veľkosť jedného stáda. Môže byť prítomných niekoľko stád. model.modifier.breedingFactor.name=Odchov z jedného stáda model.modifier.breedingFactor.shortDescription=Počet potomokov, ktoré bude každé stádo produkovať. model.modifier.buildingPriceBonus.name=Bonus ceny stavby/výroby -model.modifier.cargoPenalty.name=Znevýhodnenie nákladu +model.modifier.cargoPenalty.name=Penalizácia za náklad model.modifier.cargoPenalty.shortDescription=Zníženie bojovej efektivity za každý náklad model.modifier.colonyGoodsParty.name=Koloniálne tovarové oslavy model.modifier.consumeOnlySurplusProduction.name=Množstvo spotrebovaného prebytku @@ -1304,22 +1304,22 @@ model.modifier.conversionSkill.name=Schopnosť konverzie model.modifier.defence.name=Obranný bonus model.modifier.defence.shortDescription=Obranný Bonus model.modifier.education.teaching.turns.name=Ťahy strávené výučbou -model.modifier.exploreLostCityRumour.name=Preskúmať ruiny strateného mesta +model.modifier.exploreLostCityRumour.name=Preskúmať Povesti o stratenom meste model.modifier.exposedTilesRadius.name=Rádius nechránených polí model.modifier.fortified.name=Opevnené model.modifier.immigration.name=Prisťahovalectvo model.modifier.landPaymentModifier.name=Modifikátor platby za pozemok model.modifier.liberty.name=Sloboda -model.modifier.lineOfSightBonus.name=Bonus vzdialenosti dohľadu +model.modifier.lineOfSightBonus.name=Bonus dohľadu model.modifier.minimumColonySize.name=Minimálna veľkosť kolónie model.modifier.minimumColonySize.shortDescription=Minimálna veľkosť kolónie -model.modifier.missionaryTradeBonus.name=Bonus misionárskeho obchodu +model.modifier.missionaryTradeBonus.name=Obchodný bonus misie model.modifier.movementBonus.name=Pohybový bonus model.modifier.movementBonus.shortDescription=Jednotky tohto národa sa pohybujú rýchlejšie. -model.modifier.nativeAlarmModifier.name=Bonus na poplach domorodcov -model.modifier.nativeAlarmModifier.shortDescription=Tento národ spôsobuje nižší poplach u domorodcov. +model.modifier.nativeAlarmModifier.name=Bonus podráždenia domorodcov +model.modifier.nativeAlarmModifier.shortDescription=Tento národ spôsobuje nižšie podráždenie u domorodcov. model.modifier.nativeConvertBonus.name=Bonus na konverziu domorodcov -model.modifier.nativeConvertBonus.shortDescription=Tomuto národu konvertujú domorodci rýchlejšie. +model.modifier.nativeConvertBonus.shortDescription=Tento národ ľahšie konvertuje domorodcov. model.modifier.offence.name=Útočný bonus model.modifier.offenceAgainst.name=Útok proti model.modifier.offenceAgainst.shortDescription=Pri útoku zvyšuje šancu na víťazstvo. @@ -1328,19 +1328,19 @@ model.modifier.popularSupport.name=Ľudová podpora model.modifier.religiousUnrestBonus.name=Bonus na náboženské nepokoje model.modifier.religiousUnrestBonus.shortDescription=Tento národ spôsobuje viac náboženských nepokojov. model.modifier.sailHighSeas.name=Bonus za plavbu na šírom mori -model.modifier.shipTradePenalty.name=Znevýhodnenie obchodu loďou -model.modifier.smallMovementPenalty.name=Znevýhodnenie malého pohybu +model.modifier.shipTradePenalty.name=Penalizácia námorného obchodu +model.modifier.smallMovementPenalty.name=Malá penalizácia pohybu model.modifier.SoL.name=Synovia Slobody -model.modifier.tileTypeChangeProduction.name=Výnos s dreva +model.modifier.tileTypeChangeProduction.name=Produkcia dreva model.modifier.tileTypeChangeProduction.shortDescription=Zvyšuje množstvo získaného dreva pri vyrúbaní lesa. model.modifier.tradeBonus.name=Obchodný bonus model.modifier.tradeBonus.shortDescription=Tento národ má obchodný bonus. -model.modifier.tradeVolumePenalty.name=Znevýhodnenie obchodného objemu +model.modifier.tradeVolumePenalty.name=Penalizácia objemu obchodu model.modifier.tradeVolumePenalty.shortDescription=Znižuje objem obchodu s domorodcami. model.modifier.treasureTransportFee.name=Poplatok za prepravu pokladu model.modifier.warehouseStorage.description=Kapacita skladu -model.modifier.warehouseStorage.name=Kapacita skladu -model.modifier.warehouseStorage.shortDescription=Kapacita skladu +model.modifier.warehouseStorage.name=Skladovacia kapacita +model.modifier.warehouseStorage.shortDescription=Skladovacia kapacita model.source.ambushBonus.name=Bonus za prepadnutie model.source.amphibiousAttack.name=Obojživelný útok model.source.artilleryAgainstRaid.name=Delostrelectvo proti napadnutiu @@ -1348,16 +1348,16 @@ model.source.artilleryInTheOpen.name=Delostrelectvo na otvorenom priestranstve model.source.attackBonus.name=Útočný bonus model.source.baseDefence.name=Základná obrana model.source.baseOffence.name=Základný útok -model.source.cargoPenalty.name=Znevýhodnenie nákladu -model.source.colonyGoodsParty.name=Tovarový sviatok +model.source.cargoPenalty.name=Penalizácia za náklad +model.source.colonyGoodsParty.name=Tovarová párty model.source.fortified.name=Opevnené -model.source.movementPenalty.name=Znevýhodnenie pohybu -model.source.shipTradePenalty=Znevýhodnenie obchodu loďou -model.source.solModifier.name=Synovia slobody / Feudalisti +model.source.movementPenalty.name=Penalizácia pohybu +model.source.shipTradePenalty=Penalizácia námorného obchodu +model.source.solModifier.name=Synovia slobody / Lojalisti model.building.armory.name=Puškárstvo -model.building.armory.description=Puškárstvo vyrába z nástrojov pušky. Akonáhle populácia kolónie dosiahne počet 8, môže byť vylepšené na Zbrojnicu a keď sa Adam Smith pripojí ku Kontinentálnemu kongresu môže sa vylepšiť na Továreň na zbrane. +model.building.armory.description=Puškárstvo vyrába z nástrojov muškety. Akonáhle populácia kolónie dosiahne počet 8, môže byť vylepšené na Zbrojnicu a keď sa Adam Smith pripojí ku Kontinentálnemu kongresu môže sa vylepšiť na Továreň na zbrane.\n\nPo vybudovaní puškárstva môžete vyrábať muškety a delostrelectvo. model.building.arsenal.name=Továreň na zbrane -model.building.arsenal.description=Továreň na zbrane spotrebúva len polovicu nástrojov na výrobu pušiek oproti puškárstvu. +model.building.arsenal.description=Továreň na zbrane vyrába muškety z nástrojov.\n\nPo vybudovaní továrne na zbrane je potrebná len polovica nástrojov na výrobu muškiet. model.building.blacksmithHouse.name=Kováčska dielňa model.building.blacksmithHouse.description=Kováčska dielňa, ktorá môže byť vylepšená na železiarstvo, premieňa železnú rudu na nástroje. Nástroje sú potrebné na stavbu niektorých a vylepšenie všetkých budov. Nástroje sa takisto používajú na výrobu pušiek a nástroje používajú ku svojej práci aj priekopníci. Keď populácia kolónie dosiahne množstvo 8, železiarstvo môže byť vylepšené na železiarne za predpokladu, že zakladateľ Adam Smith sa pripojil ku Kontinentálnemu kongresu. model.building.blacksmithShop.name=Železiarstvo diff --git a/data/strings/FreeColMessages_vi.properties b/data/strings/FreeColMessages_vi.properties new file mode 100644 index 0000000000..8a4af5e881 --- /dev/null +++ b/data/strings/FreeColMessages_vi.properties @@ -0,0 +1,1914 @@ +# Messages for Vietnamese (Tiếng Việt) +# Exported from translatewiki.net +# Author: BaRaN6161 TURK +# Author: Băng Tỏa +# Author: Dinhxuanduyet +# Author: Leducthn +# Author: Max20091 +# Author: Minh Nguyen +# Author: Thuylieu +# Author: Trần Nguyễn Minh Huy +# Author: Vinhtantran +# Author: Withoutaname + +chilly=Hơi lạnh +cold=Lạnh +dry=Khô +hot=Nóng +temperate=Ôn hòa +veryDry=Khô lắm +veryHigh=Rất Cao +veryLarge=Khổng lồ +veryLow=Rất Thấp +verySmall=Rất Nhỏ +veryWet=Ướt lắm +warm=Ấm +wet=Ướt +freecol.desktopEntry.GenericName=Trò Chơi Chiến Thuật +freecol.desktopEntry.Comment=Một trò chơi chiến thuật theo lượt dựa trên "Sid Meier's Colonization". +accept=Chấp Nhận +all=Tất cả +and=và +browse=Duyệt +cancel=Hủy bỏ +client=Trình Chạy +close=Đóng +color=Màu +connect=Kết nối +current=Đang dùng +false=Sai +fill=Lấp đầy +height=Bề dài +help=Trợ giúp +high=Cao +host=Máy chủ +income=thu nhập +large=Lớn +load=Tải +low=Thấp +many=nhiều +medium=Vừa +more=thêm… +music=Nhạc +name=Tên +number=Số +no=Không +none=Không có +normal=Thường +nothing=Trống +ok=OK +options=Tùy chọn +port=Cảng +private=riêng tư +quit=Thoát +reject=Từ chối +remove=Dời +rename=Đổi tên +reset=Mặc định lại +revertToDefaults=Trở lại các mặc định +save=Lưu +scope=Điểm số +select=Chọn +server=Máy chủ +skip=Bỏ qua +small=Nhỏ +statistics=Thống kê +test=Thử +true=Đúng +unknown=Không rõ +unload=Gỡ bỏ +value=Giá trị +width=Bề ngang +yes=Có +abilities=Khả năng +activateAllUnits=Kích hoạt mọi đơn vị +activateUnit=Kích hoạt đơn vị +assignTradeRoute=Phân bổ tuyến đường thương mại +building=Công trình +capital=Thủ đô +cargo=Hàng hóa +cargoOnCarrier=Hàng hóa trên phương tiện vận chuyển +cashInTreasureTrain=Tiền mặt trong chuyến tàu kho báu +claimableRadius=Bán kính có thể yêu cầu +clearOrders=Đơn đặt hàng rõ ràng +colonists=Người định cư +colonyCenter=trung tâm thuộc địa +colopedia=Colopedia +countryName={{tag:country|%nation%}} +difficulty=Độ khó +docks=Cảng +dumpCargo=Đổ hàng +extraClaimableRadius=bán kính yêu cầu bồi thường bổ sung +finalResult=Kết quả +fortify=Củng cố +gold=Vàng +goldAmount=%amount% {{số nhiều: %amount% |one=vàng|other=vàng|default=vàng}} +goods=Bài viết tốt +goToEurope=Đến Châu Âu +goToThisTile=Đến Ô Này +immigrants=Dân nhập cư +inPort=Trong cảng +leaveShip=Rời Tàu +maximumSize=Cỡ lớn nhất +minimumSize=Cỡ nhỏ nhất +mission=Nhiệm vụ +modifiers=Chỉnh sửa +nation=Quốc gia +newWorld=Thế Giới Mới +notApplicable=N/A +payArrears=Thanh toán nợ quá hạn +player=Người chơi +purchase=Mua +recruit=Lời mời +rules=Luật chơi +sailingToAmerica=Hành trình đến Mỹ +sailingToEurope=Hành trình đi thuyền đến châu Âu +sales=Việc bán hàng +sentry=Lính canh +setSail=Khởi hành +settlement=Giải quyết/Duyệt +showProductionModifiers=Hiển thị các yếu tố điều chỉnh sản xuất +skillTaught=Học kỹ năng +startGame=Bắt đầu trò chơi +tax=Thuế +train=Xe lửa +unexplored=Chưa thám hiểm +unitType=Loại đơn vị +units=Đơn vị +list.add=Thêm +list.down=Xuống +list.edit=Sửa +list.remove=Dời +list.up=Lên +status.loadingGame=Xin chờ: Đang tải +status.savingGame=Xin chờ: Đang lưu +status.startingGame=Xin chờ: Đang khởi động +cli.arg.advantages=ADVANTAGES +cli.arg.clientOptions=OPTIONS FILE +cli.arg.debug=DEBUG-MODES +cli.arg.debugRun=TURNS[,SAVENAME] +cli.arg.difficulty=DIFFICULTY +cli.arg.dimensions=WIDTHxHEIGHT +cli.arg.directory=DIRECTORY +cli.arg.europeans=EUROPEANS +cli.arg.file=FILE +cli.arg.gui-scale=SCALE +cli.arg.locale=LOCALE +cli.arg.loglevel=LOGLEVEL +cli.arg.metaServer=HOST:PORT +cli.arg.name=NAME +cli.arg.port=PORT +cli.arg.serverIp=Địa chỉ IP +cli.arg.seed=SEED +cli.arg.timeout=TIMEOUT +cli.error.advantages=Loại ưu điểm ( %advantages% ) được mong đợi, tìm thấy: %arg% +cli.error.badTC=Lỗi khi mở bộ quy tắc %tc% . +cli.error.clientOptions=Bỏ qua tệp tùy chọn máy khách không thể đọc được: %string% +cli.error.debug=Cần có danh sách chế độ gỡ lỗi ( %modes% ). +cli.error.difficulties=Mức độ khó ( %difficulties% ) dự kiến, thực tế: %arg% +cli.error.europeans=Số lượng quốc gia châu Âu phải đạt ít nhất %min% +cli.error.gui-scale=Tỷ lệ phần trăm thang đo giao diện người dùng ( %scales% ) dự kiến, tìm thấy: %arg% +cli.error.home.noRead=Không thể đọc từ %string% . +cli.error.home.noWrite=Không thể ghi vào %string% . +cli.error.home.notDir=%string% không phải là một thư mục. +cli.error.home.notExists=Thư mục %string% không tồn tại. +cli.error.meta-server=Địa chỉ máy chủ meta không hợp lệ: %arg% +cli.error.save=Không thể đọc dữ liệu trò chơi đã lưu %string% . +cli.error.serverPort=%string% không phải là số cổng hợp lệ. +cli.error.serverIp=%string% không phải là địa chỉ IP hợp lệ của máy chủ. +cli.error.splash=Không tìm thấy tệp tin khởi động %name% . +cli.error.timeout=%string% quá ngắn (ngắn hơn %minimum% ). +cli.advantages=đặt loại ƯU ĐIỂM ( %advantages% ) +cli.check-savegame.failed=Kiểm tra tính nhất quán của file lưu game thất bại, vui lòng kiểm tra nhật ký tại %log% để biết chi tiết. +cli.check-savegame.fixed=Kiểm tra tính nhất quán của file lưu game đã thất bại nhưng đã được khắc phục, vui lòng kiểm tra nhật ký tại %log% để biết chi tiết. +cli.check-savegame.success=Kiểm tra tính nhất quán của file lưu game đã thành công, xem nhật ký tại %log% để biết chi tiết. +cli.check-savegame=Kiểm tra tính nhất quán của file lưu game đã cho. +cli.clientOptions=Tệp XML chứa các tùy chọn người dùng của máy khách. +cli.debug-run=Chạy N lượt ở chế độ gỡ lỗi, sau đó tùy chọn lưu và thoát. +cli.debug-start=Bắt đầu ngay một trò chơi chơi đơn mới +cli.debug=thiết lập các chế độ gỡ lỗi FreeCol ( %modes% ) +cli.default-locale=đặt ngôn ngữ mặc định (LANGUAGE[_COUNTRY[_VARIANT]]) +cli.difficulty=thiết lập mức độ KHÓ +cli.european-count=Đặt số lượng quốc gia được kích hoạt (các nước thuộc địa châu Âu) +cli.fast=bỏ qua tất cả các hộp thoại thiết lập +cli.font=đặt phông chữ mặc định +cli.freecol-data=Thiết lập thư mục dữ liệu của FreeCol (có một thư mục con tên là 'base') +cli.full-screen=Chạy FreeCol ở chế độ toàn màn hình +cli.gui-scale=điều chỉnh tỷ lệ các phần tử giao diện người dùng, với tùy chọn SCALE ( %scales% ) +cli.headless=chạy ở chế độ không giao diện người dùng +cli.help=Hiển thị màn hình trợ giúp này +cli.load-savegame=Tải tệp lưu trò chơi đã cho. +cli.log-console=Ghi nhật ký vào bảng điều khiển ngoài việc ghi vào tệp. +cli.log-file=Thiết lập tệp nhật ký FreeCol (mặc định là FreeCol.log) +cli.log-level=Đặt mức độ ghi nhật ký Java thành LOGLEVEL +cli.meta-server=Đặt địa chỉ và cổng cho máy chủ meta. +cli.name=Hãy cung cấp TÊN cho người chơi +cli.no-intro=bỏ qua video giới thiệu +cli.no-java-check=bỏ qua bước kiểm tra phiên bản Java +cli.no-memory-check=bỏ qua bước kiểm tra bộ nhớ +cli.no-sound=Chạy FreeCol mà không có âm thanh +cli.no-splash=bỏ qua màn hình chào mừng +cli.private=Khởi tạo một máy chủ riêng (không được công bố lên máy chủ meta) +cli.rules=Tải các quy tắc với TÊN đã cho +cli.seed=Cung cấp một SEED cho bộ tạo số giả ngẫu nhiên +cli.server=khởi động một máy chủ độc lập +cli.server-name=Chỉ định TÊN tùy chỉnh cho máy chủ +cli.server-port=Chỉ định cổng tùy chỉnh cho máy chủ +cli.server-ip=Chỉ định địa chỉ IP liên kết cho máy chủ +cli.splash=Hiển thị ảnh màn hình chờ trong khi tải trò chơi. +cli.tc=Tải toàn bộ quá trình chuyển đổi với TÊN đã cho +cli.timeout=Số giây mà máy chủ chờ câu trả lời cho một câu hỏi. +cli.user-cache-directory=thiết lập thư mục bộ nhớ cache người dùng FreeCol +cli.user-config-directory=thiết lập thư mục cấu hình người dùng FreeCol +cli.user-data-directory=đặt thư mục dữ liệu người dùng FreeCol +cli.version=Hiển thị số phiên bản và thoát. +cli.windowed=Chạy FreeCol ở chế độ cửa sổ, với tùy chọn DIMENSIONS +menuBar.colopedia=Colopedia +menuBar.game=Trò chơi +menuBar.orders=Thứ tự +menuBar.report=Báo cáo +menuBar.tools=Công cụ +menuBar.view=Xem +menuBar.statusLine=Điểm: %score% | Vàng: %gold% | Thuế: %tax%% | Năm: %year% +menuBar.debug=Gỡ lỗi +menuBar.debug.reloadResources=Tải lại kết quả +menuBar.debug.rendering=Gỡ lỗi hiển thị +menuBar.debug.addBuilding=Thêm công trình vào mỗi thuộc địa. +menuBar.debug.addFoundingFather=Thêm người cha lập quốc +menuBar.debug.addGold=Thêm vai trò +menuBar.debug.addImmigration=Thêm vấn đề nhập cư +menuBar.debug.addLiberty=Hãy mang lại tự do cho mỗi thuộc địa. +menuBar.debug.compareMaps.checkComplete=Kiểm tra hoàn tất. Không phát hiện hiện tượng mất đồng bộ. +menuBar.debug.compareMaps.problem=Đã phát hiện sự cố. Vui lòng đọc thông tin được ghi vào đầu ra chuẩn. +menuBar.debug.compareMaps=Kiểm tra hiện tượng mất đồng bộ bản đồ +menuBar.debug.displayAIMissions=Hiển thị các nhiệm vụ AI +menuBar.debug.displayAdditionalAIMissionInfo=Hiển thị thông tin nhiệm vụ AI bổ sung +menuBar.debug.displayErrorMessage=Hiển thị tin nhắn thành viên +menuBar.debug.displayEuropeStatus=Hiển thị trạng thái Châu Âu +menuBar.debug.displayMonarchPanel=Phanele Monarch hiển thị +menuBar.debug.displayPanels=Xem các trang +menuBar.debug.displayUnits=Hiện đơn vị +menuBar.debug.hideEntireMap=Ẩn Toàn Bộ Bản Đồ +menuBar.debug.memoryManager.gc=Chạy chương trình thu gom rác +menuBar.debug.memoryManager=Trình quản lý bộ nhớ +menuBar.debug.revealEntireMap=Hiện Toàn Bộ Bản Đồ +menuBar.debug.runMonarch=Thiết lập hành động tiếp theo của Monarch +menuBar.debug.searchTrace=Ghi lại toàn bộ dấu vết tìm kiếm +menuBar.debug.showColonyValue=Chứng tỏ giá trị thuộc địa +menuBar.debug.showCoordinates=Hiển thị tọa độ +menuBar.debug.showDefenceMap=Hiển thị bản đồ phòng thủ AI +menuBar.debug.showResourceKeys=Hiển thị các khóa tài nguyên +menuBar.debug.skipTurns=Bỏ lượt +menuBar.debug.stepRandomNumberGenerator=Bước tạo số ngẫu nhiên +menuBar.debug.stopSkippingTurns=Đừng bỏ lượt nữa +menuBar.debug.useAI=Sử dụng trí tuệ nhân tạo +aboutAction.name=Giới thiệu về FreeCol +activeAction.name=Kích hoạt đơn vị +assignTradeRouteAction.name=Phân bổ tuyến đường thương mại +buildColonyAction.name=Xây dựng/Tham gia thuộc địa +centerAction.name=Căn về giữa +changeAction.enterColony.name=Nhập vào thuộc địa +changeAction.name=Căn hộ tiếp theo trên gạch +changeAction.nextUnitOnTile.name=Căn hộ tiếp theo trên gạch +changeAction.selectCarrier.name=Chọn nhà mạng +changeWindowedModeAction.name=Chế độ toàn màn hình +chatAction.name=Trò chuyện +clearForestAction.name=Làm lại +clearOrdersAction.name=Đơn đặt hàng rõ ràng +colopediaAction.buildings.name=Công trình +colopediaAction.concepts.name=Khái niệm +colopediaAction.fathers.name=Các vị cha lập quốc +colopediaAction.goods.name=Bài viết tốt +colopediaAction.nations.name=Quốc gia +colopediaAction.nationTypes.name=Lợi Thế Quốc Gia +colopediaAction.resources.name=Tài nguyên bổ sung +colopediaAction.terrain.name=Các loại địa hình +colopediaAction.units.name=Đơn vị +colopediaAction.name=%object% (Colopedia) +continueAction.name=Chơi tiếp +debugAction.name=Bật chế độ sửa lỗi +declareIndependenceAction.name=Tuyên Bố Độc Lập +determineHighSeasAction.name=Xác định vùng biển quốc tế +difficultyAction.name=Hiện Mức Độ Khó +disbandUnitAction.name=Giải tán +displayBordersAction.name=Viền hiển thị +displayGridAction.name=Lưới hiển thị +displayFogOfWarAction.name=Hiển thị sương mù chiến tranh +displayTileTextAction.empty.name=Không hiển thị văn bản trong các ô +displayTileTextAction.names.name=Tên ô hiển thị +displayTileTextAction.owners.name=Chủ sở hữu gạch trưng bày +displayTileTextAction.regions.name=Hiển thị các vùng ô +endTurnAction.name=Kết thúc lượt +europeAction.name=Châu Âu +executeGotoOrdersAction.name=Thực hiện lệnh Chuyển đến đơn hàng +findSettlementAction.name=Tìm nơi định cư +fortifyAction.name=Củng cố +gameOptionsAction.name=Xem tùy chọn trò chơi +gotoAction.name=Tới +gotoTileAction.name=Tới Ô +loadAction.name=Tải +mapControlsAction.name=Điều Khiển Bản Đồ +mapEditorToolboxPanelAction.name=Hộp công cụ +mapEditorTransformPanelAction.name=Biến đổi gạch +mapEditorAction.name=Sửa đổi bản đồ +mapGeneratorOptionsAction.name=Hiện Tuỳ Chọn Tạo Bản Đồ +miniMapToggleBordersAction.name=Chuyển đổi giữa chế độ xem chính trị và kinh tế +miniMapToggleBordersAction.secondary.name=Chuyển đổi giữa chế độ xem chính trị và kinh tế (thứ cấp) +miniMapToggleFogOfWarAction.name=Chuyển đổi sương mù chiến tranh +miniMapToggleFogOfWarAction.secondary.name=Bật/tắt chế độ sương mù chiến tranh (phụ) +miniMapZoomInAction.name=Phóng to BảnĐồNhỏ +miniMapZoomInAction.secondary.name=Phóng to BảnĐồNhỏ (thứ cấp) +miniMapZoomOutAction.name=Thu nhỏ BảnĐồNhỏ +miniMapZoomOutAction.secondary.name=Thu nhỏ BảnĐồNhỏ (thứ cấp) +moveAction.E.name=Về phía Đông +moveAction.E.secondary.name=Về phía Đông (thứ cấp) +moveAction.N.name=Về phía Bắc +moveAction.N.secondary.name=Về phía Bắc (thứ cấp) +moveAction.NE.name=Về phía Đông Bắc +moveAction.NE.secondary.name=Về phía Bắc (thứ cấp) +moveAction.NW.name=Về phía Đông Bắc +moveAction.NW.secondary.name=Về phía Bắc (thứ cấp) +moveAction.S.name=Về phía Bắc +moveAction.S.secondary.name=Về phía Bắc (thứ cấp) +moveAction.SE.name=Về phía Đông Bắc +moveAction.SE.secondary.name=Về phía Bắc (thứ cấp) +moveAction.SW.name=Về phía Đông Bắc +moveAction.SW.secondary.name=Di chuyển về hướng Tây Nam (thứ cấp) +moveAction.W.name=Về phía Đông +moveAction.W.secondary.name=Về phía Bắc (thứ cấp) +newAction.name=Mới +newEmptyMapAction.name=Bản Đồ Mới +attackRangedAction.name=Tấn công tầm xa +openAction.name=Mở +plowAction.name=Chậm +preferencesAction.name=Tùy chỉnh +quitAction.name=Thoát +reconnectAction.name=Kết nối lại +renameAction.name=Đổi tên +reportCargoAction.name=Báo cáo Cốt lõi +reportColonyAction.name=Cố vấn thuộc địa +reportCongressAction.name=Đại hội Lục địa +reportEducationAction.name=Báo cáo về giáo dục +reportExplorationAction.name=Báo cáo thăm dò +reportForeignAction.name=Cố vấn Ngoại giao +reportHighScoresAction.name=Kỷ Lục +reportHistoryAction.name=Báo cáo lịch sử +reportIndianAction.name=- Người cố vấn Ấn Độ +reportLabourAction.name=Cố vấn Lao động +reportMilitaryAction.name=Tư vấn quân sự +reportNavalAction.name=Cố vấn Hải quân +reportProductionAction.name=Báo cáo về giáo dục +reportReligionAction.name=Cố vấn tôn giáo +reportRequirementsAction.accelerator=F12 +reportRequirementsAction.name=Yêu cầu +reportTradeAction.accelerator=F9 +reportTradeAction.name=Cố vấn Thuế +reportTurnAction.accelerator=F11 +reportTurnAction.name=Chạy báo cáo +retireAction.name=Về hưu +roadAction.name=Xây dựng đường +saveAction.name=Lưu +saveAndQuitAction.name=Lưu và Thoát +scaleMapAction.name=Bản đồ tỷ lệ +sentryAction.name=Lính canh +showMainAction.name=Quay lại trang +skipUnitAction.name=Bỏ qua +startMapAction.name=Ngày bắt đầu +tilePopupAction.name=Hiển thị ô +toggleViewModeAction.name=Chuyển đổi chế độ xem +tradeRouteAction.name=Các tuyến đường thương mại +unloadAction.name=Gỡ bỏ +waitAction.name=Chờ/Đơn vị tiếp theo +zoomInAction.name=Phóng to +zoomOutAction.name=Thu nhỏ +actionManager.name=Phím tắt +actionManager.shortDescription=Phím tắt +difficultyLevels.name=Mức độ khó +model.difficulty.veryEasy.name=Rất Dễ +model.difficulty.easy.name=Dễ +model.difficulty.medium.name=Vừa +model.difficulty.hard.name=Khó +model.difficulty.veryHard.name=Rất Khó +model.difficulty.custom.name=Tùy Biến +model.difficulty.custom.shortDescription=Mức độ khó có thể tùy chỉnh. +model.difficulty.immigration.name=Di dân +model.option.crossesIncrement.name=Tăng số lần giao nhau +model.option.crossesIncrement.shortDescription=Số lần vượt biên bổ sung cần thiết cho mỗi người nhập cư mới. +model.option.recruitPriceIncrease.name=Tăng giá tuyển dụng +model.option.recruitPriceIncrease.shortDescription=Làm tăng chi phí tuyển dụng người nhập cư mới. +model.option.lowerCapIncrease.name=Mức tăng trần thấp hơn +model.option.lowerCapIncrease.shortDescription=Tăng giá tuyển dụng tối thiểu cho mỗi người nhập cư mới. +model.option.priceIncreasePerType.name=Tăng giá theo từng loại sản phẩm +model.option.priceIncreasePerType.shortDescription=Liệu việc tăng giá có áp dụng cho từng loại sản phẩm riêng lẻ hay không. +model.option.priceIncrease.artillery.name=Giá pháo binh tăng +model.option.priceIncrease.artillery.shortDescription=Tăng giá bán của mỗi khẩu pháo mới. +model.option.expertStartingUnits.name=Đơn vị khởi đầu chuyên nghiệp +model.option.expertStartingUnits.shortDescription=Biến tất cả các đơn vị ban đầu thành chuyên gia. +model.option.immigrants.name=Dân nhập cư +model.option.immigrants.shortDescription=Những người nhập cư đầu tiên từ châu Âu. +model.difficulty.natives.name=Bản ngữ +model.option.landPriceFactor.name=Tỷ lệ giá đất +model.option.landPriceFactor.shortDescription=Làm tăng chi phí mua đất bản địa. +model.option.nativeConvertProbability.name=Xác suất chuyển đổi bản địa +model.option.nativeConvertProbability.shortDescription=Làm tăng khả năng người dân bản địa từ khu định cư bị phá hủy sẽ cải đạo. +model.option.burnProbability.name=Xác suất cháy khu định cư +model.option.burnProbability.shortDescription=Làm tăng khả năng người bản địa sẽ đốt phá các thuộc địa. +model.option.nativeDemands.name=Yêu cầu của người bản địa +model.option.nativeDemands.shortDescription=Làm tăng nhu cầu từ phía người bản địa. +model.option.rumourDifficulty.name=Tuỳ chỉnh độ khó +model.option.rumourDifficulty.shortDescription=Chỉ số này càng cao, thì khả năng xuất hiện những tin đồn tích cực càng thấp. +model.option.shipTradePenalty.name=hình phạt buôn bán tàu biển +model.option.shipTradePenalty.shortDescription=Mức phạt phần trăm đối với giá mà người bản địa đưa ra cho các tàu buôn. +model.option.destroySettlementScore.name=Phá hủy điểm số giải quyết +model.option.destroySettlementScore.shortDescription=Điểm phạt do phá hủy khu định cư của người bản địa +model.option.buildOnNativeLand.name=Xây dựng trên vùng đất bản địa +model.option.buildOnNativeLand.shortDescription=Liệu các thuộc địa có thể được thành lập trên đất của người bản địa hay không. +model.option.buildOnNativeLand.always.name=Luôn luôn +model.option.buildOnNativeLand.always.shortDescription=Việc xây dựng trên đất bản địa luôn luôn khả thi. +model.option.buildOnNativeLand.first.name=Tên +model.option.buildOnNativeLand.first.shortDescription=Thuộc địa đầu tiên của bạn có thể được xây dựng trên vùng đất bản địa. +model.option.buildOnNativeLand.firstAndUncontacted.name=Người đầu tiên chưa được tiếp xúc +model.option.buildOnNativeLand.firstAndUncontacted.shortDescription=Bạn có thể xây dựng thuộc địa đầu tiên trên đất của người bản địa miễn là chưa liên lạc được với bộ lạc sở hữu vùng đất đó. +model.option.buildOnNativeLand.never.name=Không bao giờ +model.option.buildOnNativeLand.never.shortDescription=Việc xây dựng trên đất của người bản địa là không được phép. +model.option.settlementNumber.name=Số lượng khu định cư bản địa +model.option.settlementNumber.shortDescription=Tùy chọn thiết lập số lượng khu định cư bản địa trên bản đồ được tạo ra. +model.option.settlementNumber.verySmall.name=Rất Nhỏ +model.option.settlementNumber.verySmall.shortDescription=Rất ít khu định cư của người bản địa +model.option.settlementNumber.small.name=Nhỏ +model.option.settlementNumber.small.shortDescription=Số lượng khu định cư bản địa +model.option.settlementNumber.medium.name=Vừa +model.option.settlementNumber.medium.shortDescription=Số lượng khu định cư bản địa +model.option.settlementNumber.large.name=Lớn +model.option.settlementNumber.large.shortDescription=Số lượng lớn các khu định cư bản địa +model.option.settlementNumber.veryLarge.name=Khổng lồ +model.option.settlementNumber.veryLarge.shortDescription=Nhiều khu định cư bản địa +model.difficulty.monarch.name=Hoàng đế +model.option.monarchMeddling.name=Sự can thiệp của nhà vua +model.option.monarchMeddling.shortDescription=Làm tăng mức độ và tính nghiêm trọng của sự can thiệp của nhà vua. +model.option.taxAdjustment.name=Khả năng điều chỉnh thuế +model.option.taxAdjustment.shortDescription=Tăng mức độ nghiêm khắc của việc tăng thuế. +model.option.mercenaryPrice.name=Giá lính đánh thuê +model.option.mercenaryPrice.shortDescription=Tăng giá các lính đánh thuê do nhà vua cung cấp. +model.option.maximumTax.name=Thuế tối đa +model.option.maximumTax.shortDescription=Mức thuế cao nhất mà nhà vua sẽ áp dụng. +model.option.monarchSupport.name=Hỗ trợ của Monarch +model.option.monarchSupport.shortDescription=Sự hỗ trợ quân sự do Quốc vương cung cấp. +model.option.treasureTransportFee.name=Phí vận chuyển kho báu +model.option.treasureTransportFee.shortDescription=Tỷ lệ phần trăm kho báu mà vương miện sẽ giữ lại để đổi lấy phí vận chuyển. +model.option.interventionBells.name=Chuông can thiệp +model.option.interventionBells.shortDescription=Số lượng chuông cần thiết để điều động Lực lượng Can thiệp. +model.option.interventionTurns.name=Sự can thiệp chuyển hướng +model.option.interventionTurns.shortDescription=Số lượt giữa các lần bổ sung vào Lực lượng Can thiệp. +model.option.refSize.name=Quy mô của Lực lượng Viễn chinh Hoàng gia +model.option.refSize.shortDescription=Số lượng và loại hình các đơn vị cấu thành Lực lượng Viễn chinh Hoàng gia. +model.option.refSize.soldiers.name=Bộ binh +model.option.refSize.soldiers.shortDescription=Số lượng đơn vị bộ binh. +model.option.refSize.dragoons.name=Tội ngựa +model.option.refSize.dragoons.shortDescription=Số lượng đơn vị kỵ binh. +model.option.refSize.menOfWar.name=Men'O'War +model.option.refSize.menOfWar.shortDescription=Số lượng tàu chiến, hay "Men'O'War". +model.option.refSize.artillery.name=Pháo binh +model.option.refSize.artillery.shortDescription=Số lượng đơn vị kỵ binh. +model.option.interventionForce.name=Sự can thiệp chuyển hướng +model.option.interventionForce.shortDescription=Lực lượng can thiệp được phái đi để hỗ trợ cuộc Chiến tranh giành độc lập của các bạn. +model.option.mercenaryForce.name=Giá lính đánh thuê +model.option.mercenaryForce.shortDescription=Lực lượng lính đánh thuê đã đề nghị hỗ trợ cho cuộc Chiến tranh giành độc lập của các bạn. +model.option.warSupportForce.name=Lực lượng Hỗ trợ Chiến tranh +model.option.warSupportForce.shortDescription=Lực lượng tối đa mà Quốc vương cung cấp để hỗ trợ các cuộc chiến của bạn. +model.option.warSupportGold.name=Vàng hỗ trợ chiến tranh +model.option.warSupportGold.shortDescription=Số vàng tối đa mà nhà vua có thể cung cấp để hỗ trợ các cuộc chiến tranh của bạn. +model.difficulty.government.name=Chính Phủ +model.option.badGovernmentLimit.name=Giới hạn chính phủ tồi tệ +model.option.badGovernmentLimit.shortDescription=Số lượng tối đa những người theo hoàng gia mà không phải chịu hình phạt về sản xuất. +model.option.veryBadGovernmentLimit.name=Giới hạn của chính phủ rất tệ +model.option.veryBadGovernmentLimit.shortDescription=Số lượng tối đa những người theo hoàng gia mà không phải chịu hình phạt tăng sản lượng. +model.option.goodGovernmentLimit.name=Giới hạn chính phủ tồi tệ +model.option.goodGovernmentLimit.shortDescription=Tỷ lệ phần trăm tối thiểu của quân nổi dậy gây ra phần thưởng sản xuất. +model.option.veryGoodGovernmentLimit.name=Giới hạn của chính phủ rất tệ +model.option.veryGoodGovernmentLimit.shortDescription=Tỷ lệ phần trăm tối thiểu của quân nổi dậy dẫn đến việc tăng tiền thưởng sản xuất. +model.difficulty.other.name=Khác +model.option.startingMoney.name=Vốn ban đầu +model.option.startingMoney.shortDescription=Số tiền bạn có khi bắt đầu trò chơi. +model.option.foundingFatherFactor.name=yếu tố người cha sáng lập +model.option.foundingFatherFactor.shortDescription=Làm tăng chi phí bầu chọn một người cha lập quốc mới. +model.option.arrearsFactor.name=Yếu tố nợ quá hạn +model.option.arrearsFactor.shortDescription=Làm tăng số tiền thuế nợ đọng của bạn ở châu Âu. +model.option.unitsThatUseNoBells.name=Những người định cư không sử dụng chuông +model.option.unitsThatUseNoBells.shortDescription=Số lượng người định cư trong một thuộc địa không sử dụng bất kỳ chiếc chuông nào. +model.option.tileProduction.name=Sản xuất gạch +model.option.tileProduction.shortDescription=Sản xuất gạch với sản lượng thay đổi. +model.option.tileProduction.veryLow.name=Rất Thấp +model.option.tileProduction.veryLow.shortDescription=Sản lượng gạch rất thấp +model.option.tileProduction.low.name=Thấp +model.option.tileProduction.low.shortDescription=Sản xuất gạch thấp +model.option.tileProduction.medium.name=Vừa +model.option.tileProduction.medium.shortDescription=Sản xuất gạch cỡ trung bình +model.option.tileProduction.high.name=Cao +model.option.tileProduction.high.shortDescription=Sản xuất gạch thấp +model.option.tileProduction.veryHigh.name=Rất Cao +model.option.tileProduction.veryHigh.shortDescription=Sản lượng gạch rất thấp +model.option.badRumour.name=Tin đồn xấu có thể xảy ra +model.option.badRumour.decription=Xác suất phần trăm một tin đồn có kết quả xấu. +model.option.goodRumour.name=Tin đồn tốt +model.option.goodRumour.decription=Tỷ lệ phần trăm khả năng tin đồn có kết quả tốt. +model.difficulty.cheat.name=Gian lận bằng AI +model.option.liftBoycottCheat.name=Hãy chấm dứt tẩy chay +model.option.liftBoycottCheat.shortDescription=Tỷ lệ phần trăm xác suất mỗi lượt chơi của người chơi AI được dỡ bỏ lệnh tẩy chay mà không cần thanh toán các khoản nợ tồn đọng. +model.option.equipScoutCheat.name=Trang bị trinh sát +model.option.equipScoutCheat.shortDescription=Tỷ lệ phần trăm xác suất mỗi lượt chơi của AI trang bị miễn phí một đơn vị trinh sát ở châu Âu. +model.option.equipPioneerCheat.name=Trang bị Tiên phong +model.option.equipPioneerCheat.shortDescription=Tỷ lệ phần trăm xác suất mỗi lượt chơi của AI trang bị miễn phí một đơn vị tiên phong ở châu Âu. +model.option.landUnitCheat.name=Nhận đơn vị đất +model.option.landUnitCheat.shortDescription=Tỷ lệ phần trăm xác suất mỗi lượt chơi của AI nhận được một đơn vị bộ binh hữu ích miễn phí ở châu Âu. +model.option.offensiveLandUnitCheat.name=Nhận đơn vị tấn công trên bộ +model.option.offensiveLandUnitCheat.shortDescription=Tỷ lệ phần trăm xác suất mỗi lượt chơi của AI nhận được một đơn vị bộ binh tấn công miễn phí ở châu Âu. +model.option.offensiveNavalUnitCheat.name=Nhận đơn vị hải quân tấn công +model.option.offensiveNavalUnitCheat.shortDescription=Tỷ lệ phần trăm xác suất mỗi lượt chơi của AI (giảm dần theo sức mạnh hải quân) xây dựng một đơn vị hải quân tấn công miễn phí ở châu Âu. +model.option.transportNavalUnitCheat.name=Nhận đơn vị vận tải hải quân +model.option.transportNavalUnitCheat.shortDescription=Tỷ lệ phần trăm mỗi lượt chơi AI xây dựng một đơn vị vận tải hải quân miễn phí ở châu Âu (nếu nó có việc cần làm để xây dựng thêm các đơn vị vận tải). +model.option.tradeProfitMultiplierCheat.name=Hệ số nhân giúp tăng lợi nhuận giao dịch bằng trí tuệ nhân tạo. +model.option.tradeProfitMultiplierCheat.shortDescription=Lợi nhuận từ bất kỳ giao dịch bán hàng nào ở châu Âu sẽ được nhân với số tiền này. +model.option.tradeProfitMultiplierCheatTurns.name=Số lượt chơi tương ứng với hệ số nhân ở trên. +model.option.tradeProfitMultiplierCheatTurns.shortDescription=Hệ số nhân lợi nhuận giao dịch của AI sẽ giảm tuyến tính cho đến khi đạt số lượt này. +gameOptions.name=Thêm tùy chọn +gameOptions.shortDescription=Thêm tùy chọn +gameOptions.map.name=Bản đồ +gameOptions.map.shortDescription=Các tùy chọn cho bảng bản đồ. +model.option.turnsToSail.name=Quay sang hướng đi thuyền +model.option.turnsToSail.shortDescription=Số vòng quay cần thiết để đi thuyền từ châu Âu đến Tân Thế giới. +model.option.settlementLimitModifier.name=Bộ điều chỉnh giới hạn thanh toán +model.option.settlementLimitModifier.shortDescription=Số tiền được cộng thêm vào giới hạn của khu định cư, chẳng hạn như số lượng toa xe có thể chế tạo. +model.option.fogOfWar.name=Sương mù chiến tranh +model.option.fogOfWar.shortDescription=Liệu các đơn vị địch nằm ngoài tầm nhìn của chúng ta có nên được ẩn nấp không? +model.option.explorationPoints.name=Điểm khám phá +model.option.explorationPoints.shortDescription=Liệu điểm khám phá có nên được trao cho tất cả các phát hiện? +model.option.amphibiousMoves.name=Di chuyển lưỡng cư +model.option.amphibiousMoves.shortDescription=Cho phép di chuyển trực tiếp vào khu định cư từ các đơn vị hải quân. +model.option.emptyTraders.name=Đơn vị giao dịch trống +model.option.emptyTraders.shortDescription=Cho phép các đơn vị thương mại trống được giao dịch với các khu định cư bản địa. +model.option.settlementActionsContactChief.name=Người liên hệ chính +model.option.settlementActionsContactChief.shortDescription=Tất cả các hành động liên quan đến việc định cư đều liên hệ với người đứng đầu và tiêu hao phần thưởng trinh sát. +model.option.enhancedMissionaries.name=Các nhà truyền giáo được tăng cường +model.option.enhancedMissionaries.shortDescription=Các nhà truyền giáo giúp cải thiện hoạt động thương mại trong khu định cư, dạy các kỹ năng và giúp mọi người hiểu hơn về môi trường xung quanh. +model.option.missionInfluence.name=Ảnh hưởng của sứ mệnh +model.option.missionInfluence.shortDescription=Sức ảnh hưởng của một phái đoàn truyền giáo lên đến mức báo động đối với người dân bản địa trong khu định cư. +model.option.giftProbability.name=Xác suất tặng quà +model.option.giftProbability.shortDescription=Xác suất phần trăm mỗi lượt chơi: một khu định cư bản địa hòa bình có nguồn tài nguyên dư thừa sẽ tặng nguồn tài nguyên đó cho một khu định cư thân thiện của người châu Âu gần đó. +model.option.demandProbability.name=Xác suất nhu cầu +model.option.demandProbability.shortDescription=Tính theo phần trăm xác suất mỗi lượt chơi, một khu định cư bản địa tức giận sẽ đòi cống nạp từ một khu định cư châu Âu phiền phức gần đó. +model.option.alarmBonusBuy.name=Ưu đãi Native Alarm khi mua hàng +model.option.alarmBonusBuy.shortDescription=Thưởng phần trăm khi mua hàng từ khu định cư của người bản địa, dựa trên 1/10 giá trị hàng hóa. +model.option.alarmBonusSell.name=Ưu đãi Native Alarm khi mua hàng +model.option.alarmBonusSell.shortDescription=Thưởng phần trăm khi mua hàng từ khu định cư của người bản địa, dựa trên 1/10 giá trị hàng hóa. +model.option.alarmBonusGift.name=Ưu đãi Native Alarm khi mua hàng +model.option.alarmBonusGift.shortDescription=Thưởng phần trăm khi mua hàng từ khu định cư của người bản địa, dựa trên 1/10 giá trị hàng hóa. +model.option.settlementNumberOfGoodsToSell.name=Bán hàng hóa bản địa +model.option.settlementNumberOfGoodsToSell.shortDescription=Số lượng các loại hàng hóa thường được bày bán tại một khu định cư bản địa. +model.option.continueFoundingFatherRecruitment.name=Tiếp tục tuyển mộ các vị Cha lập quốc +model.option.continueFoundingFatherRecruitment.shortDescription=Tiếp tục chiêu mộ các vị Cha lập quốc sau khi giành được độc lập. +model.option.teleportREF.name=Dịch chuyển tức thời REF +model.option.teleportREF.shortDescription=REF xuất hiện tại địa điểm hạ cánh cho mục tiêu đầu tiên của nó. +model.option.mapDefinedStartingPositions.name=Sử dụng vị trí xuất phát được xác định trên bản đồ (nếu có). +model.option.mapDefinedStartingPositions.shortDescription=Các vị trí khởi đầu được xác định bởi tác giả bản đồ được sử dụng nếu có. +model.option.startingPositions.name=Chỗ Đậu Máy bay +model.option.startingPositions.shortDescription=Xác định vị trí xuất phát của các cầu thủ châu Âu. +model.option.startingPositions.classic.name=Cổ điển +model.option.startingPositions.classic.shortDescription=Các quốc gia châu Âu bắt đầu từ ranh giới biển quốc tế ở phía đông của Tân Thế giới. +model.option.startingPositions.random.name=Ngẫu nhiên +model.option.startingPositions.random.shortDescription=Các quốc gia châu Âu bắt đầu đường ranh giới biển quốc tế ở bất kỳ vị trí nào trên bản đồ. +model.option.startingPositions.historical.name=Lịch sử +model.option.startingPositions.historical.shortDescription=Các quốc gia châu Âu bắt đầu ở biên giới biển rộng gần thuộc địa đầu tiên lịch sử của họ trong Thế giới mới. +model.option.initialImmigration.name=Mục tiêu nhập cư ban đầu +model.option.initialImmigration.shortDescription=Số lượng phép lai cần thực hiện trước khi cá thể di cư châu Âu đầu tiên xuất hiện. +model.option.peaceProbability.name=Xác suất hòa bình +model.option.peaceProbability.shortDescription=Tính theo tỷ lệ phần trăm khả năng hòa bình được duy trì với một AI đang tức giận. +model.option.europeanUnitImmigrationPenalty.name=hình phạt nhập cư của đơn vị châu Âu +model.option.europeanUnitImmigrationPenalty.shortDescription=Mỗi đơn vị đang chờ ở châu Âu sẽ bị phạt mỗi lượt sản xuất chéo. +model.option.playerImmigrationBonus.name=Tiền thưởng nhập cư cho người chơi +model.option.playerImmigrationBonus.shortDescription=Thưởng thêm vào tổng sản lượng chéo mỗi lượt chơi. +model.option.equipEuropeanRecruits.name=Trang bị cho tân binh châu Âu +model.option.equipEuropeanRecruits.shortDescription=Các đơn vị mới được huấn luyện hoặc tuyển mộ ở châu Âu được trang bị theo vai trò mặc định của họ. +model.option.enhancedTradeRoutes.name=Các tuyến đường thương mại được nâng cao (THỬ NGHIỆM!) +model.option.enhancedTradeRoutes.shortDescription=Hàng hóa được phân loại để tối đa hóa lượng hàng vận chuyển và tuân thủ các hạn chế nhập khẩu. +gameOptions.colony.name=Các lựa chọn thuộc địa +gameOptions.colony.shortDescription=Bao gồm các tùy chọn liên quan đến hành vi của các thuộc địa. +model.option.bellAccumulationCapped.name=Mức tích lũy chuông được giới hạn +model.option.bellAccumulationCapped.shortDescription=Các thuộc địa không thể tích lũy thêm chuông nữa một khi tỷ lệ quân nổi dậy đạt 100%. +model.option.captureUnitsUnderRepair.name=Các thiết bị thu giữ đang được sửa chữa. +model.option.captureUnitsUnderRepair.shortDescription=Chiếm giữ các đơn vị đang sửa chữa khi một thuộc địa bị chinh phục. +model.option.customIgnoreBoycott.name=Cơ quan hải quan phớt lờ cuộc tẩy chay +model.option.customIgnoreBoycott.shortDescription=Cơ quan hải quan có thể bán hàng hóa đang bị cấm vận. +model.option.customsOnCoast.name=Các trạm hải quan trên bờ biển +model.option.customsOnCoast.shortDescription=Các trạm hải quan chỉ được phép xây dựng ở các thuộc địa ven biển. +model.option.disembarkInColony.name=Đổ bộ xuống thuộc địa +model.option.disembarkInColony.shortDescription=Tất cả các đơn vị sẽ xuống tàu khi tàu sân bay cập bến thuộc địa. +model.option.expertsHaveConnections.name=Các chuyên gia có mối quan hệ +model.option.expertsHaveConnections.shortDescription=Các chuyên gia có thể sử dụng các mối quan hệ của mình để cung cấp một lượng tài nguyên tối thiểu cho quá trình sản xuất trong các nhà máy. +model.option.foundColonyDuringRebellion.name=Thành lập thuộc địa trong thời kỳ nổi loạn +model.option.foundColonyDuringRebellion.shortDescription=Người chơi có thể tiếp tục thành lập thuộc địa trong suốt Chiến tranh giành độc lập. +model.option.payForBuilding.name=Trả tiền cho việc xây dựng +model.option.payForBuilding.shortDescription=Liệu có thể hoàn thành các công trình xây dựng nhanh hơn bằng cách trả tiền cho các nguyên liệu còn thiếu? +model.option.saveProductionOverflow.name=Tiết kiệm chi phí sản xuất dư thừa +model.option.saveProductionOverflow.shortDescription=Hãy cất giữ những chiếc búa, chuông và thánh giá dư thừa. +model.option.clearHammersOnConstructionSwitch.name=Máy búa rõ ràng trên công tắc xây dựng +model.option.clearHammersOnConstructionSwitch.shortDescription=Đặt lại số búa đã tích lũy về 0 nếu vật phẩm có thể xây dựng hiện tại thay đổi. +model.option.allowStudentSelection.name=Cho phép sinh viên lựa chọn +model.option.allowStudentSelection.shortDescription=Cho phép phân công học sinh thủ công thay vì tự động. +model.option.claimAllTiles.name=Chiếm tất cả các ô +model.option.claimAllTiles.shortDescription=Hãy chiếm tất cả các ô đất liền kề có sẵn để lập thuộc địa mới. +model.option.enableUpkeep.name=Các tòa nhà cần được bảo trì (THỬ NGHIỆM) +model.option.enableUpkeep.shortDescription=Phải trả chi phí bảo trì các công trình hoặc chịu thiệt hại về sản lượng. +model.option.onlyNaturalImprovements.name=Chỉ có sự cải thiện tự nhiên +model.option.onlyNaturalImprovements.shortDescription=Chỉ những cải tiến tự nhiên trên ô đất mới góp phần vào việc sản xuất hàng hóa phi thực phẩm trên ô đất trung tâm thuộc địa. +model.option.naturalDisasters.name=Thảm họa thiên nhiên +model.option.naturalDisasters.shortDescription=Tương tự như là có thể xảy ra thảm họa tự nhiên. +gameOptions.victoryConditions.name=Điều kiện chiến thắng +gameOptions.victoryConditions.shortDescription=Các thiết lập để quyết định cách giành chiến thắng trong trò chơi. +model.option.victoryDefeatREF.name=Người chơi đầu tiên giành được độc lập +model.option.victoryDefeatREF.shortDescription=Người chơi nào là con người đầu tiên đánh bại Lực lượng Viễn chinh Hoàng gia sẽ thắng trò chơi. +model.option.victoryDefeatEuropeans.name=Tất cả các cầu thủ châu Âu khác đều bị đánh bại. +model.option.victoryDefeatEuropeans.shortDescription=Bất kỳ người chơi nào đánh bại tất cả những người chơi châu Âu khác sẽ thắng trò chơi. +model.option.victoryDefeatHumans.name=Tất cả người chơi khác đều bị đánh bại. +model.option.victoryDefeatHumans.shortDescription=Bất kỳ người chơi nào đánh bại tất cả những người chơi châu Âu khác sẽ thắng trò chơi. +gameOptions.years.name=Chọn lựa tìm kiếm +gameOptions.years.shortDescription=Bao gồm các tùy chọn liên quan đến nhiều năm đặc biệt khác nhau. +model.option.startingYear.name=Năm bắt đầu +model.option.startingYear.shortDescription=Năm mà trò chơi bắt đầu. +model.option.seasonYear.name=Mùa vụ năm +model.option.seasonYear.shortDescription=Năm đầu tiên có hai mùa. +model.option.mandatoryColonyYear.name=Năm thuộc địa bắt buộc +model.option.mandatoryColonyYear.shortDescription=Năm mà việc sở hữu thuộc địa trở thành bắt buộc. +model.option.lastYear.name=Năm cuối cùng của trò chơi +model.option.lastYear.shortDescription=Năm cuối cùng của trò chơi. +model.option.lastColonialYear.name=Năm cuối cùng của trò chơi thuộc địa +model.option.lastColonialYear.shortDescription=Năm cuối cùng của trò chơi đối với người chơi thuộc phe thuộc địa. +model.option.independenceTurn.name=Bước ngoặt độc lập +model.option.independenceTurn.shortDescription=Sẽ được cộng điểm thưởng nếu tuyên bố độc lập trước lượt này. +model.option.ages.name=độ tuổi tuyển dụng của người cha sáng lập +model.option.ages.shortDescription=Hai năm mà cân nặng của người cha lập quốc thay đổi (phân cách bằng dấu phẩy). +model.option.seasons.name=Mùa +model.option.seasons.shortDescription=Số mùa trong một năm +gameOptions.prices.name=Tùy chọn giá +gameOptions.prices.shortDescription=Chứa các tùy chọn do trò chơi tạo ra để kiểm soát giá ban đầu. +model.option.food.minimumPrice.name=Giá tối thiểu ban đầu cho thực phẩm +model.option.food.maximumPrice.name=Giá tối đa ban đầu cho thực phẩm +model.option.food.spread.name=Chênh lệch giữa giá mua và giá bán thực phẩm +model.option.sugar.minimumPrice.name=Giá tối thiểu ban đầu cho thực phẩm +model.option.sugar.maximumPrice.name=Giá tối đa ban đầu cho thực phẩm +model.option.sugar.spread.name=Chênh lệch giữa giá mua và giá bán thực phẩm +model.option.tobacco.minimumPrice.name=Giá tối thiểu ban đầu cho thực phẩm +model.option.tobacco.maximumPrice.name=Giá tối đa ban đầu cho thực phẩm +model.option.tobacco.spread.name=Chênh lệch giữa giá mua và giá bán thực phẩm +model.option.cotton.minimumPrice.name=Giá tối đa ban đầu cho thực phẩm +model.option.cotton.maximumPrice.name=Giá tối đa ban đầu cho thực phẩm +model.option.cotton.spread.name=Chênh lệch giữa giá mua và giá bán thực phẩm +model.option.furs.minimumPrice.name=Giá tối thiểu ban đầu cho thực phẩm +model.option.furs.maximumPrice.name=Giá tối đa ban đầu cho thực phẩm +model.option.furs.spread.name=Chênh lệch giữa giá mua và giá bán thực phẩm +model.option.lumber.minimumPrice.name=Giá tối đa ban đầu cho thực phẩm +model.option.lumber.maximumPrice.name=Giá tối đa ban đầu cho thực phẩm +model.option.lumber.spread.name=Chênh lệch giữa giá mua và giá bán thực phẩm +model.option.ore.minimumPrice.name=Giá tối thiểu ban đầu cho thực phẩm +model.option.ore.maximumPrice.name=Giá tối đa ban đầu cho thực phẩm +model.option.ore.spread.name=Chênh lệch giữa giá mua và giá bán thực phẩm +model.option.silver.minimumPrice.name=Giá tối đa ban đầu cho thực phẩm +model.option.silver.maximumPrice.name=Giá tối đa ban đầu cho thực phẩm +model.option.silver.spread.name=Chênh lệch giữa giá mua và giá bán thực phẩm +model.option.rum.minimumPrice.name=Giá tối thiểu ban đầu cho thực phẩm +model.option.rum.maximumPrice.name=Giá tối thiểu ban đầu cho thực phẩm +model.option.rum.spread.name=Chênh lệch giữa giá mua và giá bán thực phẩm +model.option.cigars.minimumPrice.name=Giá tối thiểu ban đầu cho thực phẩm +model.option.cigars.maximumPrice.name=Giá tối thiểu ban đầu cho thực phẩm +model.option.cigars.spread.name=Chênh lệch giữa giá mua và giá bán thực phẩm +model.option.cloth.minimumPrice.name=Giá tối đa ban đầu cho thực phẩm +model.option.cloth.maximumPrice.name=Giá tối thiểu ban đầu cho thực phẩm +model.option.cloth.spread.name=Chênh lệch giữa giá mua và giá bán thực phẩm +model.option.coats.minimumPrice.name=Giá tối thiểu ban đầu cho thực phẩm +model.option.coats.maximumPrice.name=Giá tối đa ban đầu cho thực phẩm +model.option.coats.spread.name=Chênh lệch giữa giá mua và giá bán thực phẩm +model.option.tools.minimumPrice.name=Giá tối đa ban đầu cho thực phẩm +model.option.tools.maximumPrice.name=Giá tối thiểu ban đầu cho thực phẩm +model.option.tools.spread.name=Chênh lệch giữa giá mua và giá bán thực phẩm +model.option.muskets.minimumPrice.name=Giá tối đa ban đầu cho thực phẩm +model.option.muskets.maximumPrice.name=Giá tối thiểu ban đầu cho thực phẩm +model.option.muskets.spread.name=Chênh lệch giữa giá mua và giá bán súng hỏa mai +model.option.tradeGoods.minimumPrice.name=Giá tối đa ban đầu cho thực phẩm +model.option.tradeGoods.maximumPrice.name=Giá tối thiểu ban đầu cho thực phẩm +model.option.tradeGoods.spread.name=Chênh lệch giữa giá mua và giá bán súng hỏa mai +model.option.horses.minimumPrice.name=Giá ban đầu tối thiểu cho ngựa +model.option.horses.maximumPrice.name=Giá tối thiểu ban đầu cho thực phẩm +model.option.horses.spread.name=Chênh lệch giữa giá mua và giá bán súng hỏa mai +model.option.hammers.price.name=Giá của búa khi mua các tòa nhà và đơn vị xây dựng +mapGeneratorOptions.name=Hiện Tuỳ Chọn Tạo Bản Đồ +mapGeneratorOptions.shortDescription=Các tùy chọn cho máy tạo bản đồ. +mapGeneratorOptions.landGenerator.name=Máy phát điện đất +mapGeneratorOptions.landGenerator.shortDescription=Các tùy chọn để thiết lập kích thước bản đồ và diện tích đất. +model.option.mapWidth.name=Chiều rộng bản đồ +model.option.mapWidth.shortDescription=Tùy chọn để thiết lập chiều rộng của bản đồ được tạo ra. +model.option.mapHeight.name=Độ cao bản đồ +model.option.mapHeight.shortDescription=Tùy chọn để thiết lập chiều rộng của bản đồ được tạo ra. +model.option.landMass.name=khối đất +model.option.landMass.shortDescription=Tùy chọn để thiết lập chiều rộng của bản đồ được tạo ra. +model.option.landGeneratorType.name=Loại hình địa hình (THỬ NGHIỆM!) +model.option.landGeneratorType.shortDescription=Tùy chọn để thiết lập loại trình tạo đất cần sử dụng. +model.option.landGeneratorType.classic.name=Cổ điển +model.option.landGeneratorType.classic.shortDescription=Một lục địa rộng lớn và một số hòn đảo. +model.option.landGeneratorType.continent.name=Lục địa +model.option.landGeneratorType.continent.shortDescription=Phần lớn diện tích đất liền là một lục địa duy nhất. +model.option.landGeneratorType.archipelago.name=Quần đảo +model.option.landGeneratorType.archipelago.shortDescription=Một số hòn đảo cỡ trung bình. +model.option.landGeneratorType.islands.name=Đảo +model.option.landGeneratorType.islands.shortDescription=Nhiều hòn đảo nhỏ hơn. +model.option.preferredDistanceToEdge.name=Khoảng cách ưa thích đến mép +model.option.preferredDistanceToEdge.shortDescription=Khoảng cách lý tưởng đến mép bản đồ. +model.option.maximumDistanceToEdge.name=Khoảng cách tối đa đến mép +model.option.maximumDistanceToEdge.shortDescription=Khoảng cách tối đa đến rìa bản đồ. +model.option.distanceToHighSea.name=Khoảng cách đến vùng biển quốc tế +model.option.distanceToHighSea.shortDescription=Khoảng cách lý tưởng giữa bờ biển và vùng biển quốc tế. +mapGeneratorOptions.terrainGenerator.name=Máy tạo địa hình +mapGeneratorOptions.terrainGenerator.shortDescription=Cài đặt cho số lượng rừng, núi, v.v. +model.option.minimumLatitude.name=Vĩ độ tối thiểu +model.option.minimumLatitude.shortDescription=Vĩ độ cực bắc. Giá trị âm biểu thị vĩ độ phía Bắc. +model.option.maximumLatitude.name=Vĩ độ tối đa +model.option.maximumLatitude.shortDescription=Vĩ độ cực nam. Giá trị dương biểu thị vĩ độ phía Nam. +mapGeneratorOptions.enableGreatRivers.name=Tạo điều kiện cho các dòng sông lớn +mapGeneratorOptions.enableGreatRivers.shortDescription=Cho phép tạo ra các dòng sông mà các phương tiện trên đất liền không thể vượt qua. +model.option.riverNumber.name=Số dòng sông +model.option.riverNumber.shortDescription=Tùy chọn thiết lập số lượng khu định cư bản địa trên bản đồ được tạo ra. +model.option.riverNumber.verySmall.name=Rất Nhỏ +model.option.riverNumber.verySmall.shortDescription=Rất ít sông +model.option.riverNumber.small.name=Nhỏ +model.option.riverNumber.small.shortDescription=Số lượng sông ít +model.option.riverNumber.medium.name=Vừa +model.option.riverNumber.medium.shortDescription=Số lượng sông trung bình +model.option.riverNumber.large.name=Lớn +model.option.riverNumber.large.shortDescription=Số lượng lớn các con sông +model.option.riverNumber.veryLarge.name=Rất lớn +model.option.riverNumber.veryLarge.shortDescription=Nhiều sông ngòi +model.option.mountainNumber.name=Số núi +model.option.mountainNumber.shortDescription=Tùy chọn thiết lập số lượng núi trên bản đồ được tạo ra. +model.option.mountainNumber.verySmall.name=Rất nhỏ +model.option.mountainNumber.verySmall.shortDescription=Rất ít núi +model.option.mountainNumber.small.name=Bé nhỏ +model.option.mountainNumber.small.shortDescription=Số lượng núi ít +model.option.mountainNumber.medium.name=Vừa +model.option.mountainNumber.medium.shortDescription=Số lượng núi trung bình +model.option.mountainNumber.large.name=Lớn +model.option.mountainNumber.large.shortDescription=Số lượng núi ít +model.option.mountainNumber.veryLarge.name=Rất lớn +model.option.mountainNumber.veryLarge.shortDescription=Nhiều ngọn núi +model.option.rumourNumber.name=Số lượng tin đồn về thành phố bị mất tích +model.option.rumourNumber.shortDescription=Tùy chọn thiết lập số lượng khu định cư bản địa trên bản đồ được tạo ra. +model.option.rumourNumber.verySmall.name=Rất nhỏ +model.option.rumourNumber.verySmall.shortDescription=Rất ít sông +model.option.rumourNumber.small.name=Nhỏ +model.option.rumourNumber.small.shortDescription=Số lượng sông ít +model.option.rumourNumber.medium.name=Vừa +model.option.rumourNumber.medium.shortDescription=Số lượng sông trung bình +model.option.rumourNumber.large.name=Lớn +model.option.rumourNumber.large.shortDescription=Số lượng lớn các con sông +model.option.rumourNumber.veryLarge.name=ổngô +model.option.rumourNumber.veryLarge.shortDescription=Nhiều sông ngòi +model.option.forestNumber.name=Tỷ lệ phần trăm rừng +model.option.forestNumber.shortDescription=Tùy chọn thiết lập số lượng khu định cư bản địa trên bản đồ được tạo ra. +model.option.forestNumber.verySmall.name=Rất nhỏ +model.option.forestNumber.verySmall.shortDescription=Rất ít rừng +model.option.forestNumber.small.name=Nhỏ +model.option.forestNumber.small.shortDescription=Số lượng sông ít +model.option.forestNumber.medium.name=Vừa +model.option.forestNumber.medium.shortDescription=Số lượng rừng trung bình +model.option.forestNumber.large.name=Lớn +model.option.forestNumber.large.shortDescription=Số lượng lớn các con sông +model.option.forestNumber.veryLarge.name=Khổng lồ +model.option.forestNumber.veryLarge.shortDescription=Rừng rậm phong phú +model.option.bonusNumber.name=Tỷ lệ phần trăm ô thưởng +model.option.bonusNumber.shortDescription=Tùy chọn thiết lập số lượng khu định cư bản địa trên bản đồ được tạo ra. +model.option.bonusNumber.verySmall.name=Rất Nhỏ +model.option.bonusNumber.verySmall.shortDescription=Rất ít rừng +model.option.bonusNumber.small.name=Nhỏ +model.option.bonusNumber.small.shortDescription=Số lượng sông ít +model.option.bonusNumber.medium.name=Vừa +model.option.bonusNumber.medium.shortDescription=Số lượng rừng trung bình +model.option.bonusNumber.large.name=Lớn +model.option.bonusNumber.large.shortDescription=Số lượng lớn các con sông +model.option.bonusNumber.veryLarge.name=Khổng lồ +model.option.bonusNumber.veryLarge.shortDescription=Rừng rậm phong phú +model.option.humidity.name=Độ ẩm +model.option.humidity.shortDescription=Tùy chọn để thiết lập độ ẩm trung bình của bản đồ. +model.option.humidity.veryDry.name=Khô lắm +model.option.humidity.veryDry.shortDescription=Độ ẩm rất thấp +model.option.humidity.dry.name=Khô +model.option.humidity.dry.shortDescription=Độ ẩm thấp +model.option.humidity.normal.name=Thường +model.option.humidity.normal.shortDescription=Độ ẩm bình thường +model.option.humidity.wet.name=Ướt +model.option.humidity.wet.shortDescription=Độ ẩm cao +model.option.humidity.veryWet.name=Ướt lắm +model.option.humidity.veryWet.shortDescription=Độ ẩm rất thấp +model.option.temperature.name=Nhiệt độ +model.option.temperature.shortDescription=Tùy chọn để thiết lập độ ẩm trung bình của bản đồ. +model.option.temperature.cold.name=Lạnh +model.option.temperature.cold.shortDescription=Nhiệt độ rất thấp +model.option.temperature.chilly.name=Hơi lạnh +model.option.temperature.chilly.shortDescription=Nhiệt độ thấp +model.option.temperature.temperate.name=Ôn hòa +model.option.temperature.temperate.shortDescription=Nhiệt độ bình thường +model.option.temperature.warm.name=Ấm +model.option.temperature.warm.shortDescription=Nhiệt độ thấp +model.option.temperature.hot.name=Nóng +model.option.temperature.hot.shortDescription=Nhiệt độ rất thấp +mapGeneratorOptions.import.name=Nhập +mapGeneratorOptions.import.shortDescription=Các tùy chọn để nhập bản đồ hoặc trò chơi đã lưu. +model.option.importFile.name=Nhập tập tin +model.option.importFile.shortDescription=Tệp tin cần nhập. Đó có thể là bản đồ hoặc tệp lưu trò chơi. +model.option.importTerrain.name=Nhập địa hình +model.option.importTerrain.shortDescription=Cho phép nhập dữ liệu địa hình. +model.option.importBonuses.name=Tiền thưởng nhập khẩu +model.option.importBonuses.shortDescription=Cho phép nhập khẩu tiền thưởng. +model.option.importRumours.name=Nhập khẩu Thành viên +model.option.importRumours.shortDescription=Cho phép nhập khẩu những tin đồn về các thành phố đã mất. +model.option.importSettlements.name=thanh toán nhập khẩu +model.option.importSettlements.shortDescription=Cho phép nhập khẩu các khu định cư bản địa. +clientOptions.name=Tùy chỉnh +clientOptions.shortDescription=Các tùy chọn ưu tiên của khách hàng +clientOptions.personal.name=Riêng tư +clientOptions.personal.shortDescription=Các tùy chọn dành riêng cho người chơi. +model.option.playerName.name=Tên người chơi +clientOptions.display.name=Trưng bày +clientOptions.display.shortDescription=Định nghĩa độ phân giải, kích thước và hiệu suất. +model.option.fullscreenDisplayMode.name=Chế độ hiển thị toàn màn hình +model.option.fullscreenDisplayMode.shortDescription=Độ phân giải, tốc độ làm mới và độ sâu màu khi chạy ở chế độ toàn màn hình. +model.option.fullscreenDisplayMode.automatic=Mặc định +model.option.displayScaling.name=Tỷ lệ hiển thị +model.option.displayScaling.shortDescription=Xác định kích thước của các bảng có kích thước cố định, ví dụ như bản đồ thu nhỏ. +model.option.displayScaling.automatic=Tự động +model.option.manualMainFontSize.name=Tự định nghĩa kích thước phông chữ chính. +model.option.manualMainFontSize.shortDescription=Cho phép người dùng tự định nghĩa kích thước phông chữ chính thay vì đặt mặc định dựa trên độ phân giải màn hình (DPI). +model.option.mainFontSize.name=Kích thước phông chữ chính +model.option.mainFontSize.shortDescription=Thay đổi kích thước phông chữ chính. +clientOptions.interface.name=Giao diện +clientOptions.interface.shortDescription=Chứa các thiết lập để điều chỉnh giao diện của trò chơi. +clientOptions.interface.mapView.name=Bản đồ chính +clientOptions.interface.mapView.shortDescription=Điều chỉnh cách hiển thị bản đồ chính. +clientOptions.interface.mapControls.name=Điều Khiển Bản Đồ +clientOptions.interface.mapControls.shortDescription=Các tùy chọn để điều chỉnh bản đồ thu nhỏ và các bảng điều khiển khác được kết nối trực tiếp với bản đồ. +model.option.languageOption.name=Ngôn ngữ +model.option.languageOption.shortDescription=Thiết lập ngôn ngữ được sử dụng trong trò chơi. +clientOptions.gui.languageOption.autoDetectLanguage=Tự động phát hiện ngôn ngữ +model.option.guiMinNumberToDisplayGoodsCount.name=Hiển thị số lượng hàng hóa tại +model.option.guiMinNumberToDisplayGoodsCount.shortDescription=Số lượng hàng hóa sẽ được hiển thị khi lớn hơn hoặc bằng con số này. +model.option.guiMaxNumberOfGoodsImages.name=Số lượng tối đa hình ảnh sản phẩm +model.option.guiMaxNumberOfGoodsImages.shortDescription=Số lượng tối đa hình ảnh sản phẩm được phép hiển thị. +model.option.guiMinNumberToDisplayGoods.name=Giấu hàng hóa trong kho khi số lượng ít hơn +model.option.guiMinNumberToDisplayGoods.shortDescription=Hàng hóa sẽ được trưng bày trong khu dân cư khi số lượng lớn hơn hoặc bằng con số này. +model.option.alwaysCenter.name=Luôn căn giữa các ô đã chọn +model.option.alwaysCenter.shortDescription=Luôn căn chỉnh lại vị trí trung tâm trên ô vừa được chọn. +model.option.jumpToActiveUnit.name=Chuyển đến đơn vị đang hoạt động +model.option.jumpToActiveUnit.shortDescription=Luôn căn chỉnh lại về vị trí trung tâm trên đơn vị mới được chọn. +model.option.mapScrollOnDrag.name=Đơn vị di chuyển khi kéo các đơn vị +model.option.mapScrollOnDrag.shortDescription=Cho phép cuộn trang khi kéo các đơn vị trên bản đồ. +model.option.autoScroll.name=Tự động cuộn bảng bản đồ +model.option.autoScroll.shortDescription=Bật tính năng tự động cuộn khi chuột chạm vào các cạnh của bản đồ. +model.option.displayCompassRose.name=Hiển thị la bàn +model.option.displayCompassRose.shortDescription=Có nên hiển thị la bàn hay không. +model.option.displayMapControls.name=Hiển thị các điều khiển bản đồ +model.option.displayMapControls.shortDescription=Xác định xem có hiển thị các điều khiển bản đồ theo mặc định hay không. +model.option.displayGrid.name=Lưới hiển thị +model.option.displayGrid.shortDescription=Xác định xem có hiển thị các điều khiển bản đồ theo mặc định hay không. +model.option.displayBorders.name=Viền hiển thị +model.option.displayBorders.shortDescription=Xác định xem có hiển thị các điều khiển bản đồ theo mặc định hay không. +model.option.displayFogOfWar.name=Hiển thị sương mù chiến tranh +model.option.displayFogOfWar.shortDescription=Xác định xem có hiển thị các điều khiển bản đồ theo mặc định hay không. +model.option.unitLastMoveDelay.name=Độ trễ di chuyển cuối cùng của đơn vị +model.option.unitLastMoveDelay.shortDescription=Liệu có nên tạm dừng ngắn ở nước đi cuối cùng của một đơn vị hay không. +model.option.usePixmaps.name=Sử dụng pixmap để lưu trữ hình ảnh. +model.option.usePixmaps.shortDescription=Hãy thử tắt chức năng này nếu tốc độ di chuyển thông thường của thiết bị rất chậm. +model.option.useOpenGL.name=Bật OpenGL +model.option.useopenGL.shortDescription=Hãy thử bật chức năng này nếu giao diện người dùng (GUI) hoạt động rất chậm và tắt đi nếu nó bị lỗi. +model.option.useXRender.name=Bật XRender +model.option.useXRender.shortDescription=Một tùy chọn khác có thể khắc phục tình trạng giao diện người dùng đồ họa (GUI) rất chậm. +model.option.useTerrainAnimations.name=Bật hoạt ảnh địa hình +model.option.useTerrainAnimations.shortDescription=Tạo hiệu ứng động cho địa hình như đại dương và sông ngòi. +model.option.rememberPanelPositions.name=Hãy nhớ các vị trí trong hội đồng +model.option.rememberPanelPositions.shortDescription=Hãy nhớ vị trí của các tấm bảng khác nhau. +model.option.rememberPanelSizes.name=Hãy nhớ kích thước tấm. +model.option.rememberPanelSizes.shortDescription=Hãy nhớ kích thước của các tấm khác nhau. +model.option.smoothRendering.name=Hiển thị mượt mà +model.option.smoothRendering.shortDescription=Cho phép hiển thị bản đồ thu nhỏ mượt mà khi thu nhỏ. +model.option.disableGrayLayer.name=Tắt hình nền khi kết thúc lượt chơi +model.option.disableGrayLayer.shortDescription=Tùy chọn để tắt tính năng chuyển sang nền xám khi kết thúc. +model.option.miniMapToggleFogOfWar.name=Bật/tắt chế độ sương mù chiến tranh trên bản đồ nhỏ +model.option.miniMapToggleFogOfWar.shortDescription=Nếu được chọn: Hiển thị sương mù chiến tranh trên bản đồ thu nhỏ. +model.option.miniMapToggleBorders.name=Bật/tắt viền trên bản đồ thu nhỏ +model.option.miniMapToggleBorders.shortDescription=Nếu được chọn: Hiển thị sương mù chiến tranh trên bản đồ thu nhỏ. +model.option.mapControls.name=Điều Khiển Bản Đồ +model.option.mapControls.shortDescription=Loại điều khiển bản đồ nào cần hiển thị? +clientOptions.gui.mapControls.CornerMapControls.name=Góc +clientOptions.gui.mapControls.CornerMapControls.shortDescription=Các nút điều khiển bản đồ nằm ở các góc và cạnh dưới. +clientOptions.gui.mapControls.ClassicMapControls.name=Cổ điển +clientOptions.gui.mapControls.ClassicMapControls.shortDescription=Các nút điều khiển bản đồ nằm ở cạnh phải. +model.option.color.background.name=Màu nền +model.option.color.background.shortDescription=Khi bản đồ thu nhỏ được tối đa hóa, màu này sẽ bao quanh bản đồ và vùng sương mù chiến tranh. +clientOptions.minimap.color.background.black=Đen +clientOptions.minimap.color.background.gray.dark.very=Màu xám rất đậm +clientOptions.minimap.color.background.gray.dark=Xám đậm +clientOptions.minimap.color.background.gray=Xám +clientOptions.minimap.color.background.gray.light=Xám nhạt +clientOptions.minimap.color.background.gray.light.very=Màu xám rất nhạt +clientOptions.minimap.color.background.blue.light=Xanh nhạt +model.option.displayTileText.name=Hiển thị văn bản dạng ô +model.option.displayTileText.shortDescription=Nội dung văn bản cần hiển thị trong các ô là gì? +clientOptions.gui.displayTileText.empty.name=Trống +clientOptions.gui.displayTileText.empty.shortDescription=Hiển thị văn bản +clientOptions.gui.displayTileText.names.name=Tên ô +clientOptions.gui.displayTileText.names.shortDescription=Hiển thị loại địa hình +clientOptions.gui.displayTileText.owners.name=Chủ sở hữu gạch +clientOptions.gui.displayTileText.owners.shortDescription=Hiển thị quốc gia của chủ sở hữu ô (nếu có). +clientOptions.gui.displayTileText.regions.name=Vùng gạch +clientOptions.gui.displayTileText.regions.shortDescription=Hiển thị khu vực mà ô gạch thuộc về. +model.option.displayColonyLabels.name=Nhãn thuộc địa +model.option.displayColonyLabels.shortDescription=Kiểu dáng nhãn mác của thuộc địa. +clientOptions.gui.displayColonyLabels.none.name=Không có +clientOptions.gui.displayColonyLabels.none.shortDescription=Không dán nhãn cho các thuộc địa +clientOptions.gui.displayColonyLabels.classic.name=Cổ điển +clientOptions.gui.displayColonyLabels.classic.shortDescription=Ghi nhãn các khuẩn lạc với tên và kích thước. +clientOptions.gui.displayColonyLabels.modern.name=Hiện đại +clientOptions.gui.displayColonyLabels.modern.shortDescription=Nhãn thuộc địa phức hợp bao gồm tiền thưởng sản xuất và bất kỳ công trình đang xây dựng nào. +model.option.colonyComparator.name=Sắp xếp các thuộc địa theo +model.option.colonyComparator.shortDescription=Xác định cách phân loại các đàn gia súc. +clientOptions.gui.colonyComparator.byName.name=Tên +clientOptions.gui.colonyComparator.byName.shortDescription=Sắp xếp theo thứ tự bảng chữ cái theo tên +clientOptions.gui.colonyComparator.byAge.name=Tuổi +clientOptions.gui.colonyComparator.byAge.shortDescription=Sắp xếp theo thứ tự xây dựng +clientOptions.gui.colonyComparator.byPosition.name=Vị trí +clientOptions.gui.colonyComparator.byPosition.shortDescription=Sắp xếp theo vị trí địa lý +clientOptions.gui.colonyComparator.bySize.name=Kích cỡ +clientOptions.gui.colonyComparator.bySize.shortDescription=Sắp xếp từ lớn nhất đến nhỏ nhất +clientOptions.gui.colonyComparator.bySoL.name=SoL +clientOptions.gui.colonyComparator.bySoL.shortDescription=Sắp xếp theo thứ tự giảm dần về tự do. +model.option.defaultZoomLevel.name=Mức độ thu phóng mặc định +model.option.defaultZoomLevel.shortDescription=Mức độ thu phóng mặc định mà bản đồ thu nhỏ sử dụng. +model.option.graphicsQuality.name=Chất lượng khi hiển thị đồ họa +model.option.graphicsQuality.shortDescription=Thiết lập chất lượng khi hiển thị đồ họa. Chọn chất lượng cao hơn có thể gây ra hiện tượng giật hình và/hoặc độ trễ khi nhấp chuột vào bản đồ. +clientOptions.gui.graphicsQuality.lowest=Thấp nhất +clientOptions.gui.graphicsQuality.low=Thấp +clientOptions.gui.graphicsQuality.normal=Bình thường +clientOptions.gui.graphicsQuality.high=Cao +clientOptions.gui.graphicsQuality.highest=Cao nhất +model.option.moveAnimationSpeed.name=Tốc độ hoạt ảnh di chuyển cho các đơn vị của chúng tôi +model.option.moveAnimationSpeed.shortDescription=Thay đổi tốc độ hoạt ảnh trượt của các đơn vị trong hệ thống của chúng ta. +clientOptions.gui.moveAnimationSpeed.off=Tắt +clientOptions.gui.moveAnimationSpeed.slow=Chậm +clientOptions.gui.moveAnimationSpeed.normal=Bình thường +clientOptions.gui.moveAnimationSpeed.fast=Nhanh +model.option.enemyMoveAnimationSpeed.name=Tốc độ hoạt ảnh di chuyển của kẻ thù +model.option.enemyMoveAnimationSpeed.shortDescription=Thay đổi tốc độ hoạt ảnh trượt của các đơn vị địch. +clientOptions.gui.enemyMoveAnimationSpeed.off=Tắt +clientOptions.gui.enemyMoveAnimationSpeed.slow=Chậm +clientOptions.gui.enemyMoveAnimationSpeed.normal=Bình thường +clientOptions.gui.enemyMoveAnimationSpeed.fast=Nhanh +model.option.friendlyMoveAnimationSpeed.name=Tốc độ hoạt ảnh di chuyển thân thiện +model.option.friendlyMoveAnimationSpeed.shortDescription=Thay đổi tốc độ hoạt ảnh trượt của các đơn vị trong hệ thống của chúng ta. +clientOptions.gui.friendlyMoveAnimationSpeed.off=Tắt +clientOptions.gui.friendlyMoveAnimationSpeed.slow=Chậm +clientOptions.gui.friendlyMoveAnimationSpeed.normal=Bình thường +clientOptions.gui.friendlyMoveAnimationSpeed.fast=Nhanh +clientOptions.messages.name=Thông báo +clientOptions.messages.shortDescription=Các tùy chọn để bật/tắt thông báo. +model.option.guiMessagesGroupBy.name=Nhóm tin nhắn theo +model.option.guiMessagesGroupBy.shortDescription=Xác định cách thức nhóm các tin nhắn lại với nhau. +clientOptions.messages.guiMessagesGroupBy.nothing.name=Không gì +clientOptions.messages.guiMessagesGroupBy.nothing.shortDescription=Các tin nhắn chưa được sắp xếp. +clientOptions.messages.guiMessagesGroupBy.type.name=Loại +clientOptions.messages.guiMessagesGroupBy.type.shortDescription=Các tin nhắn được nhóm theo loại +clientOptions.messages.guiMessagesGroupBy.source.name=Nguồn +clientOptions.messages.guiMessagesGroupBy.source.shortDescription=Các tin nhắn được nhóm lại theo nguyên nhân gây ra tin nhắn đó. +model.option.guiShowBuildingCompleted.name=Thông báo hoàn thành công trình +model.option.guiShowBuildingCompleted.shortDescription=Xác định xem có hiển thị thông báo hoàn thành công trình vào đầu mỗi lượt chơi hay không. +model.option.guiShowCombatResult.name=Thông điệp chiến đấu +model.option.guiShowCombatResult.shortDescription=Xác định xem có hiển thị kết quả chiến đấu vào đầu mỗi lượt hay không. +model.option.guiShowDemands.name=Yêu cầu của người bản địa +model.option.guiShowDemands.shortDescription=Xác định xem có hiển thị thông báo hoàn thành công trình vào đầu mỗi lượt chơi hay không. +model.option.guiShowDisasters.name=Các thảm họa +model.option.guiShowDisasters.shortDescription=Xác định xem có hiển thị kết quả chiến đấu vào đầu mỗi lượt hay không. +model.option.guiShowForeignDiplomacy.name=Thông điệp ngoại giao +model.option.guiShowForeignDiplomacy.shortDescription=Xác định xem có hiển thị các thông điệp ngoại giao hay không. +model.option.guiShowGifts.name=Tài năng bản địa +model.option.guiShowGifts.shortDescription=Xác định xem có hiển thị thông báo hoàn thành công trình vào đầu mỗi lượt chơi hay không. +model.option.guiShowGoodsMovement.name=Vận chuyển hàng hóa +model.option.guiShowGoodsMovement.shortDescription=Xác định xem có hiển thị chi tiết về sự di chuyển hàng hóa hay không. +model.option.guiShowGovernmentEfficiency.name=Thông điệp về hiệu quả hoạt động của chính phủ +model.option.guiShowGovernmentEfficiency.shortDescription=Xác định xem có hiển thị thông báo hoàn thành công trình vào đầu mỗi lượt chơi hay không. +model.option.guiShowMarketPrices.name=Thông điệp về giá thị trường +model.option.guiShowMarketPrices.shortDescription=Xác định xem có hiển thị kết quả chiến đấu vào đầu mỗi lượt hay không. +model.option.guiShowMissingGoods.name=Hàng hóa bị mất +model.option.guiShowMissingGoods.shortDescription=Xác định xem có hiển thị thông báo hoàn thành công trình vào đầu mỗi lượt chơi hay không. +model.option.guiShowSonsOfLiberty.name=Thông điệp của Hội Con trai Tự do +model.option.guiShowSonsOfLiberty.shortDescription=Xác định xem có hiển thị kết quả chiến đấu vào đầu mỗi lượt hay không. +model.option.guiShowTutorial.name=Thông báo hướng dẫn +model.option.guiShowTutorial.shortDescription=Hiện các thông báo hướng dẫn +model.option.guiShowUnitAdded.name=Thông điệp của những người định cư mới +model.option.guiShowUnitAdded.shortDescription=Xác định xem có hiển thị kết quả chiến đấu vào đầu mỗi lượt hay không. +model.option.guiShowUnitArrived.name=Thông báo khi đơn vị đến +model.option.guiShowUnitArrived.shortDescription=Xác định xem có hiển thị thông báo cho các thiết bị đến châu Âu hay không. +model.option.guiShowUnitDemoted.name=Thông báo hạ cấp đơn vị +model.option.guiShowUnitDemoted.shortDescription=Xác định xem có hiển thị các thông điệp ngoại giao hay không. +model.option.guiShowUnitImproved.name=Thông báo cải tiến đơn vị +model.option.guiShowUnitImproved.shortDescription=Xác định xem có hiển thị kết quả chiến đấu vào đầu mỗi lượt hay không. +model.option.guiShowUnitLost.name=Thông báo mất mát đơn vị +model.option.guiShowUnitLost.shortDescription=Xác định xem có hiển thị thông báo về tổn thất đơn vị hay không. +model.option.guiShowUnitRepaired.name=Thông báo sửa chữa thiết bị +model.option.guiShowUnitRepaired.shortDescription=Xác định xem có hiển thị các thông điệp ngoại giao hay không. +model.option.guiShowWarehouseCapacity.name=Thông báo về sức chứa kho +model.option.guiShowWarehouseCapacity.shortDescription=Xác định xem có hiển thị kết quả chiến đấu vào đầu mỗi lượt hay không. +model.option.guiShowWarning.name=Bài viết tìm kiếm +model.option.guiShowWarning.shortDescription=Xác định xem có hiển thị các thông báo cảnh báo khác hay không. +model.option.guiShowColonyWarnings.name=Cảnh báo về địa điểm thuộc địa +model.option.guiShowColonyWarnings.shortDescription=Xác định xem có hiển thị cảnh báo về vị trí thuộc địa hay không. +model.option.guiShowPreCombat.name=Phân tích trước trận chiến +model.option.guiShowPreCombat.shortDescription=Xác định xem có hiển thị phân tích trước trận chiến hay không. +model.option.guiShowNotBestTile.name=Không phải loại gạch tốt nhất +model.option.guiShowNotBestTile.shortDescription=Xác định xem có nên cảnh báo về các thiết bị không hoạt động trên ô gạch tốt nhất hiện có hay không. +model.option.guiShowRegionNaming.name=Đặt tên khu vực +model.option.guiShowRegionNaming.shortDescription=Hiển thị hộp thoại đặt tên vùng trong khi khám phá. +model.option.colonyReport.name=Báo cáo thuộc địa +model.option.colonyReport.shortDescription=Một bản tóm tắt hoạt động trong mỗi thuộc địa. +clientOptions.messages.colonyReport.classic.name=Cổ điển +clientOptions.messages.colonyReport.classic.shortDescription=Một báo cáo chi tiết về đàn gia súc, kèm nhiều hình ảnh minh họa. +clientOptions.messages.colonyReport.compact.name=Nhỏ gọn +clientOptions.messages.colonyReport.compact.shortDescription=Bản báo cáo ngắn gọn về đàn ong, cố gắng thể hiện càng nhiều thông tin càng tốt chỉ trong một dòng ngắn gọn cho mỗi đàn. +model.option.labourReport.name=Báo cáo Lao động +model.option.labourReport.shortDescription=Một bản tóm tắt hoạt động trong mỗi thuộc địa. +clientOptions.messages.labourReport.classic.name=Cổ điển +clientOptions.messages.labourReport.classic.shortDescription=Báo cáo lao động kinh điển. +clientOptions.messages.labourReport.compact.name=Nhỏ gọn +clientOptions.messages.labourReport.compact.shortDescription=Một phiên bản ngắn gọn hơn của báo cáo kinh điển. +clientOptions.savegames.name=Trò chơi đã lưu +clientOptions.savegames.shortDescription=Các trang đã lưu +model.option.showSavegameSettings.name=Hộp thoại lưu trò chơi +model.option.showSavegameSettings.shortDescription=Hiển thị hộp thoại để thiết lập các tùy chọn máy chủ khi tải trò chơi đã lưu. +clientOptions.savegames.showSavegameSettings.never.name=Không bao giờ +clientOptions.savegames.showSavegameSettings.never.shortDescription=Không bao giờ hiển thị hộp thoại tùy chọn máy chủ +clientOptions.savegames.showSavegameSettings.multiplayer.name=Nhiều người chơi +clientOptions.savegames.showSavegameSettings.multiplayer.shortDescription=Chỉ hiển thị hộp thoại tùy chọn máy chủ cho các trò chơi đã lưu nhiều người chơi. +clientOptions.savegames.showSavegameSettings.always.name=Lúc bao giờ +clientOptions.savegames.showSavegameSettings.always.shortDescription=Luôn hiển thị hộp thoại tùy chọn máy chủ +model.option.autosavePeriod.name=Tự động lưu sau mỗi x lượt +model.option.autosavePeriod.shortDescription=Thời gian để tự động lưu trò chơi và sử dụng 0 để vô hiệu hóa tính năng này. +model.option.autosaveValidity.name=Xóa các tệp tự động lưu sau x ngày +model.option.autosaveValidity.shortDescription=Thời gian (tính bằng ngày) mà tệp tự động lưu có hiệu lực sau khi tạo. Đặt thành 0 để bỏ qua điều kiện này. +model.option.autosaveDelete.name=Xóa các tệp tự động lưu +model.option.autosaveDelete.shortDescription=Hãy xóa các tập tin tự động lưu cũ khi bắt đầu trò chơi mới. +model.option.confirmSaveOverwrite.name=Xác nhận lưu ghi đè +model.option.confirmSaveOverwrite.shortDescription=Tùy chọn xác nhận việc ghi đè lên các tệp hiện có. +model.option.autoSavePrefix.name=Tiền tố tự động lưu +model.option.autoSavePrefix.shortDescription=Tiền tố cho tên tệp tự động lưu. +model.option.lastTurnName.name=Tên tệp lượt cuối +model.option.lastTurnName.shortDescription=Gốc từ dùng để đặt tên tập tin lưu lượt chơi cuối cùng. +model.option.beforeLastTurnName.name=Tên tập tin trước lượt chơi cuối cùng +model.option.beforeLastTurnName.shortDescription=Gốc từ dùng để đặt tên tệp lưu trước lượt chơi cuối cùng. +clientOptions.warehouse.name=Cài đặt kho hàng +clientOptions.warehouse.shortDescription=Thay đổi cài đặt mặc định cho kho hàng và hải quan. +model.option.customStock.name=Hàng tồn kho mặc định của Custom House +model.option.customStock.shortDescription=Lượng hàng tồn kho mà hải quan cần dự trữ khi bán hàng hóa. +model.option.lowLevel.name=Lời cảnh báo thấp +model.option.lowLevel.shortDescription=Tạo cảnh báo khi giá cổ phiếu giảm xuống dưới mức này. +model.option.highLevel.name=Cảnh báo cấp cao +model.option.highLevel.shortDescription=Tạo cảnh báo khi lượng hàng tồn kho vượt quá mức này. +model.option.stockAccountsForProduction.name=Tài khoản dự trữ cho sản xuất +model.option.stockAccountsForProduction.shortDescription=Các tuyến thương mại kiểm tra số lượng hàng hóa, bao gồm cả dự báo sản lượng, để xác định xem có nên ghé thăm điểm dừng chân đó hay không. +clientOptions.audio.name=Âm thanh +clientOptions.audio.shortDescription=Cài đặt video +clientOptions.audio.audioMixer.automatic=Tự động phát hiện đầu ra âm thanh +model.option.audioMixer.name=Khả năng phát âm +model.option.audioMixer.shortDescription=Thiết bị được sử dụng khi phát âm thanh. +model.option.musicVolume.name=Âm lượng nhạc +model.option.musicVolume.shortDescription=Âm lượng nhạc +model.option.audioVolume.name=Âm lượng +model.option.audioVolume.shortDescription=Âm lượng +model.option.soundEffectsVolume.name=Âm lượng hiệu ứng âm thanh +model.option.soundEffectsVolume.shortDescription=Âm lượng hiệu ứng âm thanh +model.option.audioAlerts.name=Cảnh báo âm thanh +model.option.audioAlerts.shortDescription=Bật cảnh báo âm thanh +clientOptions.other.name=Khác +clientOptions.other.shortDescription=Các lựa chọn không thuộc bất kỳ danh mục nào khác. +model.option.autoloadEmigrants.name=Lái xe cho người di cư trên đường thủy đến Mỹ +model.option.autoloadEmigrants.shortDescription=Hãy xin phép được đưa người di cư lên tàu khi tàu đó đi đến Mỹ. +model.option.autoloadSentries.name=Tự động nạp các đơn vị canh gác khi có phương tiện vận chuyển phù hợp đến. +model.option.autoloadSentries.shortDescription=Các đơn vị canh gác sẽ tự động lên tàu sân bay có sẵn. +model.option.autoEndTurn.name=Tự động kết thúc vòng quay +model.option.autoEndTurn.shortDescription=Tự động kết thúc lượt chơi khi không còn đơn vị nào để di chuyển nữa. +model.option.showEndTurnDialog.name=Kết thúc cuộc hội thoại +model.option.showEndTurnDialog.shortDescription=Hiển thị hộp thoại kết thúc lượt nếu một số đơn vị vẫn có thể di chuyển. +model.option.indianDemandResponse.name=Đáp lại các yêu cầu của Ấn Độ +model.option.indianDemandResponse.shortDescription=Điều gì phải làm khi người bản địa yêu cầu hoặc yêu cầu hàng hóa. +clientOptions.other.indianDemandResponse.ask.name=Hỏi +clientOptions.other.indianDemandResponse.ask.shortDescription=Hỏi bạn nên làm gì +clientOptions.other.indianDemandResponse.accept.name=Chấp nhận +clientOptions.other.indianDemandResponse.accept.shortDescription=Chấp nhận mọi yêu cầu của người bản địa +clientOptions.other.indianDemandResponse.reject.name=Từ chối +clientOptions.other.indianDemandResponse.reject.shortDescription=Hãy bác bỏ mọi yêu cầu của người bản địa. +model.option.unloadOverflowResponse.name=Tải tràn +model.option.unloadOverflowResponse.shortDescription=Phải làm gì khi kho hàng bị quá tải do xe vận chuyển dỡ hàng? +clientOptions.other.unloadOverflowResponse.ask.name=Hỏi +clientOptions.other.unloadOverflowResponse.ask.shortDescription=Hỏi bạn nên làm gì +clientOptions.other.unloadOverflowResponse.never.name=Không bao giờ +clientOptions.other.unloadOverflowResponse.never.shortDescription=Tuyệt đối không được dỡ hàng hóa có thể làm tràn kho. +clientOptions.other.unloadOverflowResponse.always.name=Lúc bao giờ +clientOptions.other.unloadOverflowResponse.always.shortDescription=Luôn luôn dỡ hàng ngay cả khi hàng hóa tràn ra khỏi kho. +clientOptions.mods.name=chế độ +clientOptions.mods.shortDescription=Các tùy chọn để kích hoạt chỉnh sửa trò chơi. +clientOptions.mods.userMods.name=Người dùng chỉnh sửa +clientOptions.mods.userMods.shortDescription=Tùy chọn cho phép chỉnh sửa trò chơi. +clientOptions.etc.name=Vân vân +model.ability.addTaxToBells.name=Thêm thuế vào chuông +model.ability.addTaxToBells.shortDescription=Thuế suất đóng vai trò như một khoản thưởng cho việc sản xuất chuông. +model.ability.alwaysOfferedPeace.name=Luôn mang lại sự bình yên +model.ability.alwaysOfferedPeace.shortDescrption=Các quốc gia châu Âu luôn sẵn sàng đề nghị hòa bình. +model.ability.ambushBonus.name=Tiền thưởng phục kích +model.ability.ambushBonus.shortDescription=Nhận thưởng khi phục kích tấn công các đơn vị ở khu vực trống trải. +model.ability.ambushPenalty.name=Hình phạt phục kích +model.ability.ambushPenalty.shortDescription=Quốc gia này phải chịu hình phạt do bị phục kích. +model.ability.ambushTerrain.name=Địa hình phục kích +model.ability.ambushTerrain.shortDescription=Địa hình này tạo điều kiện cho các cuộc phục kích xảy ra. +model.ability.armed.name=Có vũ trang +model.ability.armed.shortDescription=Các đơn vị được trang bị vũ khí +model.ability.autoProduction.name=Sản xuất ô tô +model.ability.autoProduction.shortDescription=Sản xuất hàng hóa ngay cả khi không có sản phẩm nào hiện có. +model.ability.automaticEquipment.name=Thiết bị ô tô +model.ability.automaticEquipment.shortDescription=Các đơn vị có thể tự động trang bị để bảo vệ khu định cư. +model.ability.automaticPromotion.name=Tạo tự động +model.ability.automaticPromotion.shortDescription=Các đơn vị sẽ tự động được thăng cấp nếu giành chiến thắng trong trận chiến. +model.ability.avoidExcessProduction.name=Tránh sản xuất dư thừa +model.ability.avoidExcessProduction.shortDescription=Không bao giờ sản xuất nhiều hàng hóa hơn khả năng lưu trữ. +model.ability.betterForeignAffairsReport.name=Báo cáo ngoại giao được cải thiện +model.ability.betterForeignAffairsReport.shortDescription=Báo cáo về ngoại giao bao gồm thông tin bổ sung. +model.ability.bombard.name=Pháo binh +model.ability.bombard.shortDescription=Các đơn vị có khả năng ném bom +model.ability.bombardShips.name=Tàu bắn phá +model.ability.bombardShips.shortDescription=Pháo kích tàu địch trên các ô nước liền kề. +model.ability.bornInColony.name=Sinh ra ở thuộc địa +model.ability.bornInColony.shortDescription=Các đơn vị sinh ra trong một thuộc địa +model.ability.bornInIndianSettlement.name=Sinh ra trong khu định cư của người bản địa +model.ability.bornInIndianSettlement.shortDescription=Các đơn vị sinh ra trong khu định cư bản địa +model.ability.build.name=Xây dựng +model.ability.build.shortDescription=Khả năng chế tạo các đơn vị, thiết bị hoặc công trình, đôi khi là các loại cụ thể. +model.ability.buildCustomHouse.name=Xây nhà theo thiết kế riêng +model.ability.buildCustomHouse.shortDescription=Khả năng xây dựng nhà hải quan +model.ability.buildFactory.name=Xây dựng nhà máy +model.ability.buildFactory.shortDescription=Khả năng xây dựng các tòa nhà cấp nhà máy +model.ability.canBeCaptured.name=Có thể bị bắt giữ +model.ability.canBeCaptured.shortDescription=Các đơn vị có thể bị bắt giữ +model.ability.canBeEquipped.name=Có thể trang bị +model.ability.canBeEquipped.shortDescription=Các đơn vị có thể bị bắt giữ +model.ability.canRecruitUnit.name=Tuyển quân +model.ability.canRecruitUnit.shortDescription=Quốc gia này có khả năng tuyển quân. +model.ability.captureEquipment.name=Có thể chụp ảnh thiết bị +model.ability.captureEquipment.shortDescription=Khả năng thu thập thiết bị +model.ability.captureGoods.name=Thu giữ hàng hóa +model.ability.captureGoods.shortDescription=Đơn vị này có khả năng thu giữ hàng hóa. +model.ability.captureUnits.name=Có thể bắt giữ các đơn vị +model.ability.captureUnits.shortDescription=Khả năng bắt giữ các đơn vị trong chiến đấu +model.ability.carryGoods.name=Chở hàng hóa +model.ability.carryGoods.shortDescription=Thiết bị này có khả năng vận chuyển hàng hóa. +model.ability.carryTreasure.name=Có thể mang kho báu +model.ability.carryTreasure.shortDescription=Đơn vị này có thể mang theo kho báu +model.ability.carryUnits.name=Đơn vị mang +model.ability.carryUnits.shortDescription=Thiết bị này có khả năng vận chuyển hàng hóa. +model.ability.coastalOnly.name=Chỉ ven biển +model.ability.coastalOnly.shortDescription=Giới hạn một số vật liệu xây dựng chỉ cho các thuộc địa ven biển +model.ability.customHouseTradesWithForeignCountries.name=Hải quan thương mại quốc tế +model.ability.customHouseTradesWithForeignCountries.shortDescription=Bán hàng cho nước ngoài thông qua hải quan. +model.ability.demandTribute.name=đòi cống nạp +model.ability.demandTribute.shortDescription=Đơn vị này có thể đòi cống nạp từ khu định cư của kẻ thù. +model.ability.demoteOnAllEquipLost.name=Giáng chức do mất mát thiết bị +model.ability.demoteOnAllEquipLost.shortDescription=Đơn vị này sẽ bị hạ cấp nếu mất hết trang thiết bị. +model.ability.denounceHeresy.name=Lên án dị giáo +model.ability.denounceHeresy.shortDescription=Các đơn vị có thể tố cáo sự dị giáo của nhiệm vụ địch. +model.ability.disposeOnAllEquipLost.name=Giáng chức do mất mát thiết bị +model.ability.disposeOnAllEquipLost.shortDescription=Chiếc máy này sẽ bị phá hủy nếu mất tất cả thiết bị của nó. +model.ability.disposeOnCombatLoss.name=Phá hủy khi thua trận +model.ability.disposeOnCombatLoss.shortDescription=Đơn vị này sẽ bị tiêu hủy nếu thua trận chiến. +model.ability.dressMissionary.name=Giói cho người truyền giáo +model.ability.dressMissionary.shortDescription=Biến một đơn vị thành nhà truyền giáo (không chuyên). +model.ability.electFoundingFather.name=Bầu chọn các vị Cha lập quốc +model.ability.electFoundingFather.shortDescription=Quốc gia này có khả năng bầu chọn các vị Cha lập quốc. +model.ability.establishMission.name=Thiết lập sứ mệnh +model.ability.establishMission.shortDescription=Khả năng thiết lập sứ mệnh +model.ability.evadeAttack.name=Né tránh đòn tấn công +model.ability.evadeAttack.shortDescription=Đơn vị này có khả năng né tránh các đòn tấn công. +model.ability.expertMissionary.name=Nhà truyền giáo chuyên nghiệp +model.ability.expertMissionary.shortDescription=Đơn vị này có thể hoạt động như một nhà truyền giáo chuyên nghiệp. +model.ability.expertPioneer.name=Khả năng hoạt động như một chuyên gia tiên phong +model.ability.expertPioneer.shortDescription=Đơn vị này có thể đóng vai trò là người tiên phong chuyên nghiệp. +model.ability.expertScout.name=Có khả năng hoạt động như một chuyên gia trinh sát. +model.ability.expertScout.shortDescription=Đơn vị này có thể đóng vai trò như một trinh sát chuyên nghiệp. +model.ability.expertSoldier.name=Khả năng hoạt động như một chuyên gia tiên phong +model.ability.expertSoldier.shortDescription=Đơn vị này có thể đóng vai trò là người tiên phong chuyên nghiệp. +model.ability.expertsUseConnections.name=Các chuyên gia có mối quan hệ +model.ability.expertsUseConnections.shortDescription=Các đơn vị chuyên nghiệp phải thu mua nguyên liệu thô ngay cả khi không có sẵn. +model.ability.export.name=Hàng xuất khẩu +model.ability.export.shortDescription=Có thể xuất khẩu hàng hóa trực tiếp sang châu Âu. +model.ability.foundColony.name=Đã tìm thấy thuộc địa +model.ability.foundColony.shortDescription=Đơn vị này có khả năng thành lập một thuộc địa mới. +model.ability.foundInLostCity.name=Được tìm thấy trong những thành phố đã mất +model.ability.foundInLostCity.shortDescription=Một loại đơn vị được tìm thấy trong các thành phố đã mất. +model.ability.foundsColonies.name=Thành lập thuộc địa +model.ability.foundsColonies.shortDescription=Đơn vị này có khả năng thành lập một thuộc địa mới. +model.ability.hasPort.name=Lối ra biển +model.ability.hasPort.shortDescription=Vị trí này có đường ra biển trực tiếp hoặc gián tiếp. +model.ability.ignoreEuropeanWars.name=Bỏ qua các cuộc chiến tranh ở châu Âu +model.ability.ignoreEuropeanWars.shortDescription=Việc tuyên chiến ở châu Âu không còn ảnh hưởng đến quốc gia này nữa. +model.ability.improveTerain.name=Nhập địa hình +model.ability.improveTerain.shortDescription=Đơn vị này có khả năng cải thiện địa hình. +model.ability.inciteNatives.name=Kích động người bản địa +model.ability.inciteNatives.shortDescription=Đơn vị này có thể kích động các quốc gia bản địa chống lại một quốc gia thù địch. +model.ability.independenceDeclared.name=Tuyên ngôn độc lập +model.ability.independenceDeclared.shortDescription=Đất nước này tuyên bố độc lập. +model.ability.independentNation.name=Quốc gia độc lập +model.ability.independentNation.shortDescription=Một quốc gia độc lập +model.ability.mercenaryUnit.name=Đơn vị lính đánh thuê +model.ability.mercenaryUnit.shortDescription=Đơn vị này thường thấy trong lực lượng lính đánh thuê. +model.ability.mounted.name=Đã lắp đặt +model.ability.mounted.shortDescription=Các đơn vị được trang bị vũ khí +model.ability.moveToEurope.name=Chuyển đến châu Âu +model.ability.moveToEurope.shortDescription=Ô gạch này cho phép các đơn vị di chuyển đến châu Âu. +model.ability.multipleAttacks.name=Nhiều cuộc tấn công +model.ability.multipleAttacks.shortDescription=Đơn vị này có thể tấn công nhiều lần. +model.ability.native.name=Ấn Độ +model.ability.native.shortDescription=Người Mỹ bản địa +model.ability.navalUnit.name=Đơn vị hải quân +model.ability.navalUnit.shortDescription=Đây là một đơn vị hải quân. +model.ability.negotiate.name=Thương lượng +model.ability.negotiate.shortDescription=Các đơn vị có thể đàm phán với thị trưởng của một thuộc địa. +model.ability.person.name=Người +model.ability.person.shortDescription=Đơn vị này là một người. +model.ability.pillageUnprotectedColony.name=Làng +model.ability.pillageUnprotectedColony.shortDescription=Có thể cướp phá các thuộc địa không được bảo vệ. +model.ability.piracy.name=Cướp biển +model.ability.piracy.shortDescription=Đây là một đơn vị cướp biển. +model.ability.plunderNatives.name=Cướp bóc thổ dân +model.ability.plunderNatives.shortDescription=Tăng cường số tiền cướp được từ việc phá hủy các khu định cư của người bản địa. +model.ability.produceInWater.name=Sản phẩm được trồng trong nước +model.ability.produceInWater.shortDescription=Các đơn vị có thể sử dụng cả ô nước và ô đất. +model.ability.refUnit.name=Đơn vị REF +model.ability.refUnit.shortDescription=Đây là một đơn vị của REF +model.ability.repairUnits.name=Đơn vị sửa chữa +model.ability.repairUnits.shortDescription=Có thể sửa chữa một số loại thiết bị bị hư hỏng. +model.ability.royalExpeditionaryForce.name=Lực lượng Viễn chinh Hoàng gia +model.ability.royalExpeditionaryForce.shortDescription=Một quốc gia thuộc Lực lượng Viễn chinh Hoàng gia +model.ability.rumoursAlwaysPositive.name=Tin đồn luôn tích cực +model.ability.rumoursAlwaysPositive.shortDescription=Việc điều tra tin đồn luôn mang lại kết quả tích cực. +model.ability.seeAllColonies.name=Xem tất cả các thuộc địa +model.ability.seeAllColonies.shortDescription=Có thể nhìn thấy tất cả các thuộc địa nước ngoài +model.ability.selectRecruit.name=Tuyển dụng +model.ability.selectRecruit.shortDescription=Khả năng tuyển chọn nhân sự +model.ability.speakWithChief.name=Hãy nói chuyện với trưởng phòng. +model.ability.speakWithChief.shortDescription=Đơn vị này có thể liên lạc với người đứng đầu một khu định cư bản địa. +model.ability.spyOnColony.name=Gián điệp thuộc địa +model.ability.spyOnColony.shortDescription=Đơn vị này có thể do thám các thuộc địa nước ngoài. +model.ability.supportUnit.name=Hỗ trợ dự án +model.ability.supportUnit.shortDescription=Đơn vị này thường thấy trong lực lượng lính đánh thuê. +model.ability.teach.name=Dạy kỹ năng +model.ability.teach.shortDescription=Các đơn vị chuyên gia có thể truyền đạt kỹ năng của họ cho người khác. +model.ability.tradeWithForeignColonies.name=Giao thương với các thuộc địa nước ngoài +model.ability.tradeWithForeignColonies.shortDescription=Khả năng giao thương với các thuộc địa nước ngoài +model.ability.undead.name=Chưa đọc +model.ability.undead.shortDescription=Một đơn vị đến từ thế giới bên kia. +model.modifier.amphibiousAttack.name=Cuộc tấn công đổ bộ +model.modifier.artilleryAgainstRaid.name=Pháo binh chống lại cuộc đột kích +model.modifier.artilleryInTheOpen.name=Pháo binh ngoài trời +model.modifier.attackBonus.name=Thưởng tấn công +model.modifier.bigMovementPenalty.name=Hình phạt di chuyển lớn +model.modifier.bombardBonus.name=Tiền thưởng pháo kích +model.modifier.bombardBonus.shortDescription=Các đơn vị của quốc gia này được hưởng lợi từ phần thưởng Pháo kích. +model.modifier.breedingDivisor.name=Quy mô đàn +model.modifier.breedingDivisor.shortDescription=Kích thước của một đàn. Có thể có nhiều đàn. +model.modifier.breedingFactor.name=Số con non trên mỗi đàn +model.modifier.breedingFactor.shortDescription=Số lượng con non mà mỗi đàn sinh ra. +model.modifier.buildingPriceBonus.name=Ưu đãi giá xây dựng +model.modifier.cargoPenalty.name=Phạt hàng hóa +model.modifier.cargoPenalty.shortDescription=Mức phạt cho mỗi lô hàng ảnh hưởng đến hiệu quả chiến đấu. +model.modifier.colonyGoodsParty.name=Đảng hàng hóa thuộc địa +model.modifier.consumeOnlySurplusProduction.name=Lượng hàng dư thừa đã tiêu thụ +model.modifier.consumeOnlySurplusProduction.shortDescription=Chỉ tiêu thụ một phần sản lượng dư thừa, chứ không phải hàng hóa dự trữ. +model.modifier.conversionAlarmRate.name=Báo động chuyển đổi +model.modifier.conversionSkill.name=Kỹ năng chuyển đổi +model.modifier.defence.name=Thưởng phòng thủ +model.modifier.defence.shortDescription=Thưởng phòng thủ +model.modifier.education.teaching.turns.name=Số lượt dành cho việc giảng dạy +model.modifier.exploreLostCityRumour.name=Khám phá thành phố thất lạc Rumor +model.modifier.exposedTilesRadius.name=Bán kính gạch lộ ra +model.modifier.fortified.name=Được tăng cường +model.modifier.immigration.name=Di dân +model.modifier.landPaymentModifier.name=Bộ điều chỉnh thanh toán đất đai +model.modifier.liberty.name=Tự do +model.modifier.lineOfSightBonus.name=Thưởng tầm nhìn +model.modifier.minimumColonySize.name=Kích thước đàn tối thiểu +model.modifier.minimumColonySize.shortDescription=Kích thước đàn tối thiểu +model.modifier.missionaryTradeBonus.name=Tiền thưởng thương mại của nhà truyền giáo +model.modifier.movementBonus.name=Vai trò Phong trào +model.modifier.movementBonus.shortDescription=Các đơn vị của quốc gia này di chuyển nhanh hơn. +model.modifier.nativeAlarmModifier.name=Tiền thưởng báo thức gốc +model.modifier.nativeAlarmModifier.shortDescription=Quốc gia này gây ra ít lo ngại hơn cho người bản địa. +model.modifier.nativeConvertBonus.name=Tiền thưởng chuyển đổi bản địa +model.modifier.nativeConvertBonus.shortDescription=Quốc gia này thu hút thêm nhiều người bản địa cải đạo. +model.modifier.offence.name=Tiền thưởng tấn công +model.modifier.offenceAgainst.name=Vi phạm +model.modifier.offenceAgainst.shortDescription=Tăng khả năng chiến thắng khi tấn công. +model.modifier.peaceTreaty.name=Hiệp ước hòa bình +model.modifier.popularSupport.name=Sự ủng hộ của công chúng +model.modifier.religiousUnrestBonus.name=Tiền thưởng bất ổn tôn giáo +model.modifier.religiousUnrestBonus.shortDescription=Quốc gia này gây ra nhiều bất ổn tôn giáo hơn. +model.modifier.sailHighSeas.name=Thưởng khi đi thuyền trên biển khơi +model.modifier.shipTradePenalty.name=hình phạt buôn bán tàu biển +model.modifier.smallMovementPenalty.name=Hình phạt di chuyển lớn +model.modifier.SoL.name=Con trai của Tự do +model.modifier.tileTypeChangeProduction.name=Năng suất gỗ +model.modifier.tileTypeChangeProduction.shortDescription=Tăng sản lượng gỗ thu được khi khai phá rừng. +model.modifier.tradeBonus.name=Thưởng giao dịch +model.modifier.tradeBonus.shortDescription=Quốc gia này có ưu đãi thương mại. +model.modifier.tradeVolumePenalty.name=phạt khối lượng giao dịch +model.modifier.tradeVolumePenalty.shortDescription=Làm giảm khối lượng giao thương với người bản địa. +model.modifier.treasureTransportFee.name=Phí vận chuyển kho báu +model.modifier.warehouseStorage.description=Kho chứa hàng +model.modifier.warehouseStorage.name=Kho chứa hàng +model.modifier.warehouseStorage.shortDescription=Kho chứa hàng +model.source.ambushBonus.name=Tiền thưởng phục kích +model.source.amphibiousAttack.name=Cuộc tấn công đổ bộ +model.source.artilleryAgainstRaid.name=Pháo binh chống lại cuộc đột kích +model.source.artilleryInTheOpen.name=Pháo binh ngoài trời +model.source.attackBonus.name=Thưởng tấn công +model.source.baseDefence.name=Phòng thủ căn cứ +model.source.baseOffence.name=Tấn công cơ bản +model.source.cargoPenalty.name=Phạt hàng hóa +model.source.colonyGoodsParty.name=Tiệc hàng hóa +model.source.fortified.name=Được tăng cường +model.source.movementPenalty.name=Hình phạt di chuyển lớn +model.source.shipTradePenalty=hình phạt buôn bán tàu biển +model.source.solModifier.name=Hội Con trai của Tự do / Đảng Bảo thủ +model.building.armory.name=Kho vũ khí +model.building.armory.description=Xưởng vũ khí được sử dụng để sản xuất súng hỏa mai từ các công cụ. Ngay khi dân số đạt 8 người, xưởng vũ khí có thể được nâng cấp thành kho đạn và sau đó thành kho vũ khí lớn, với điều kiện Adam Smith đã gia nhập Quốc hội Lục địa. Sau khi xây dựng xưởng vũ khí, bạn được phép sản xuất súng hỏa mai và pháo binh. +model.building.arsenal.name=Arsenal +model.building.arsenal.description=Xưởng vũ khí được sử dụng để sản xuất súng hỏa mai từ các công cụ. Sau khi xây dựng xưởng vũ khí, chỉ cần một nửa số công cụ để sản xuất súng hỏa mai. +model.building.blacksmithHouse.name=Nhà của thợ rèn +model.building.blacksmithHouse.description=Nhà của thợ rèn, có thể được nâng cấp thành xưởng rèn, được sử dụng để chuyển đổi quặng thành công cụ. Công cụ cần thiết để xây dựng một số loại công trình và nâng cấp tất cả các loại công trình. Công cụ cũng được những người tiên phong sử dụng và để sản xuất súng hỏa mai. Khi dân số của thuộc địa đạt đến 8 người, xưởng rèn có thể được thay thế bằng xưởng luyện sắt, với điều kiện Adam Smith đã gia nhập Quốc hội Lục địa. +model.building.blacksmithShop.name=Xưởng thợ rèn +model.building.blacksmithShop.description=Xưởng rèn, có thể được nâng cấp thành xưởng luyện kim, được sử dụng để chuyển đổi quặng thành công cụ. Công cụ cần thiết để xây dựng một số loại công trình và nâng cấp tất cả các loại công trình. Công cụ cũng được những người tiên phong sử dụng và để sản xuất súng hỏa mai. Khi dân số của thuộc địa đạt đến 8 người, xưởng rèn có thể được thay thế bằng xưởng luyện kim, với điều kiện Adam Smith đã gia nhập Quốc hội Lục địa. Xưởng rèn giúp tăng sản lượng công cụ. +model.building.carpenterHouse.name=Nhà của thợ mộc +model.building.carpenterHouse.description=Nhà của người thợ mộc, có thể được nâng cấp thành xưởng cưa khi dân số thuộc địa đạt 3 người, được sử dụng để chuyển đổi gỗ thành búa. Búa là nguyên liệu cần thiết để xây dựng hoặc nâng cấp tất cả các loại công trình. +model.building.cathedral.name=Thánh đường +model.building.cathedral.description=Một thuộc địa có dân số từ 3 người trở lên có thể xây dựng một nhà thờ, và nhà thờ này có thể được nâng cấp thành nhà thờ chính tòa ngay khi dân số đạt 8 người. Tự do tôn giáo của Tân Thế giới (được biểu tượng hóa bằng thánh giá) dẫn đến sự gia tăng di cư từ châu Âu. Sau khi xây dựng nhà thờ chính tòa, sản lượng thánh giá sẽ tăng lên. +model.building.chapel.name=Nhà nguyện +model.building.chapel.description=Nhà nguyện là nơi để người dân thuộc địa của bạn thực hành tôn giáo. Nhà nguyện tự sản xuất một lượng nhỏ thánh giá, nhưng không được phép cử mục sư đến làm việc ở đây. Trước tiên, bạn cần nâng cấp nhà nguyện của mình thành nhà thờ. +model.building.church.name=Nhà thờ +model.building.church.description=Một thuộc địa có dân số từ 3 người trở lên có thể xây dựng một nhà thờ, và nhà thờ này có thể được nâng cấp thành nhà thờ chính tòa ngay khi dân số đạt 8 người. Tự do tôn giáo của Tân Thế giới (được biểu tượng hóa bằng thánh giá) dẫn đến sự gia tăng di cư từ châu Âu. Sau khi xây dựng nhà thờ chính tòa, sản lượng thánh giá sẽ tăng lên. +model.building.cigarFactory.name=Nhà máy sản xuất xì gà +model.building.cigarFactory.description=Nhà máy sản xuất xì gà, vốn không thể nâng cấp, được sử dụng để sản xuất xì gà từ thuốc lá. Nhà máy sản xuất xì gà giúp tăng sản lượng xì gà. +model.building.college.name=Trường Cao đẳng +model.building.college.description=Một thuộc địa có dân số ít nhất 4 người có thể xây dựng một trường học, cho phép một số thợ thủ công lành nghề dạy nghề cho những người dân thuộc địa chưa có kỹ năng. Ngay khi dân số đạt 8 người, trường học có thể được nâng cấp thành trường cao đẳng, nơi hai người dân thuộc địa có thể dạy thêm các nghề khác. Khi dân số đạt 10 người, trường cao đẳng có thể được thay thế bằng trường đại học, nơi ba người dân thuộc địa có thể dạy tất cả các nghề. Trường cao đẳng cho phép giảng dạy 2 kỹ năng. +model.building.country.name=Đồng cỏ +model.building.country.description=Đồng cỏ là một khu vực gần thuộc địa của bạn, nơi ngựa của bạn được tự do đi lại. Xây dựng chuồng ngựa sẽ làm tăng sản lượng ngựa. +model.building.customHouse.name=Âm thanh tùy chỉnh +model.building.customHouse.description=Cơ quan hải quan, có thể được xây dựng ngay khi Peter Stuyvesant gia nhập Quốc hội Lục địa, cho phép thuộc địa xuất khẩu hàng hóa trực tiếp sang châu Âu mà không cần tàu thuyền. Ngoài ra, nó cho phép giao thương với các cường quốc nước ngoài sau khi tuyên bố độc lập. Tùy chọn, nó cũng có thể bỏ qua các lệnh tẩy chay. +model.building.depot.name=Kho +model.building.depot.description=Kho chứa này lưu trữ đủ loại hàng hóa. Ban đầu, kho có sức chứa 100 đơn vị mỗi loại hàng hóa, nhưng có thể nâng cấp thành nhà kho với sức chứa 200 đơn vị. Xây dựng thêm khu mở rộng nhà kho sẽ tăng sức chứa lên 300 đơn vị. +model.building.distillerHouse.name=Nhà chưng cất rượu +model.building.distillerHouse.description=Ngôi nhà của người chưng cất rượu, có thể được nâng cấp thành nhà máy chưng cất rượu rum, được sử dụng để sản xuất rượu rum từ đường. Khi Adam Smith gia nhập Quốc hội Lục địa và dân số thuộc địa đạt ít nhất 8 người, nhà máy chưng cất rượu rum có thể được thay thế bằng nhà máy sản xuất rượu rum. +model.building.docks.name=Cảng +model.building.docks.description=Bến tàu cho phép người dân thuộc địa đánh bắt cá trên các ô biển liền kề với thuộc địa. Ngay khi dân số đạt ít nhất 4 người, nó có thể được nâng cấp thành ụ tàu khô, cho phép thuộc địa sửa chữa các tàu bị hư hỏng. Khi dân số thuộc địa đạt 8 người, nó có thể được nâng cấp tiếp thành xưởng đóng tàu, cho phép thuộc địa đóng tàu mới.\n\nXây dựng bến tàu cho phép đánh bắt cá. +model.building.drydock.name=Drydock +model.building.drydock.description=Xưởng sửa chữa tàu cho phép người dân thuộc địa sản xuất cá trên các ô biển liền kề với thuộc địa, và cho phép sửa chữa tàu. Khi dân số thuộc địa đạt 8 người, nó có thể được nâng cấp lên thành xưởng đóng tàu, cho phép thuộc địa đóng tàu mới.\n\nViệc xây dựng xưởng sửa chữa tàu cho phép sửa chữa tàu. +model.building.fort.name=Pháo đài +model.building.fort.description=Pháo đài, chỉ có thể được xây dựng sau khi xây dựng một công sự, bảo vệ những người định cư khỏi các cuộc tấn công. Pháo đài cung cấp sự bảo vệ và bắn phá các tàu cướp biển và các đơn vị hải quân địch trên các ô biển liền kề. Pháo đài có thể được thay thế bằng một pháo đài kiên cố ngay khi dân số đạt 8 người.\n\nXây dựng một pháo đài kiên cố sẽ tăng khả năng phòng thủ lên 150%. +model.building.fortress.name=Pháo đài +model.building.fortress.description=Pháo đài, có thể được xây dựng sau khi xây dựng pháo đài và khi dân số đạt 8 người, bảo vệ người dân thuộc địa khỏi các cuộc tấn công. Pháo đài cung cấp sự bảo vệ và bắn phá các tàu cướp biển và các đơn vị hải quân địch trên các ô biển liền kề.\n\nXây dựng pháo đài tăng khả năng phòng thủ lên 200%. +model.building.furFactory.name=Nhà máy lông thú +model.building.furFactory.description=Nhà máy sản xuất xì gà, vốn không thể nâng cấp, được sử dụng để sản xuất xì gà từ thuốc lá. Nhà máy sản xuất xì gà giúp tăng sản lượng xì gà. +model.building.furTraderHouse.name=Nhà của thương nhân buôn lông thú +model.building.furTraderHouse.description=Ngôi nhà của thương nhân buôn lông thú, có thể được nâng cấp thành trạm buôn lông thú, được sử dụng để sản xuất áo khoác từ lông thú. Khi dân số thuộc địa đạt đến 6 người, nó có thể được nâng cấp hơn nữa thành nhà máy sản xuất lông thú, với điều kiện Adam Smith đã gia nhập Quốc hội Lục địa. +model.building.furTradingPost.name=trạm buôn bán lông thú +model.building.furTradingPost.description=Trạm buôn bán lông thú, có thể được nâng cấp thành nhà máy sản xuất lông thú, được sử dụng để sản xuất áo khoác từ lông thú. Khi dân số thuộc địa đạt đến 6 người, nó có thể được nâng cấp hơn nữa thành nhà máy sản xuất lông thú, với điều kiện Adam Smith đã gia nhập Quốc hội Lục địa. Trạm buôn bán lông thú giúp tăng sản lượng áo khoác. +model.building.ironWorks.name=Xưởng sắt +model.building.ironWorks.description=Xưởng luyện sắt, vốn không thể nâng cấp, được sử dụng để chuyển hóa quặng thành công cụ. Công cụ cần thiết để xây dựng một số loại công trình nhất định và để nâng cấp tất cả các loại công trình. Công cụ cũng được những người tiên phong sử dụng và để sản xuất súng hỏa mai. Xưởng luyện sắt giúp tăng sản lượng công cụ. +model.building.lumberMill.name=Năng suất gỗ +model.building.lumberMill.description=Xưởng cưa, vốn không thể nâng cấp, được sử dụng để chuyển đổi gỗ thành búa. Búa là nguyên liệu cần thiết để xây dựng hoặc nâng cấp tất cả các loại công trình. Xưởng cưa giúp tăng sản lượng búa. +model.building.magazine.name=Tạp chí +model.building.magazine.description=Kho chứa này được dùng để sản xuất súng hỏa mai từ các công cụ. Kho chứa có thể được nâng cấp thành kho vũ khí, với điều kiện Adam Smith gia nhập Quốc hội Lục địa. Sau khi xây dựng kho chứa, sản lượng súng hỏa mai tăng 100%. +model.building.newspaper.name=Báo +model.building.newspaper.description=Tờ báo, chỉ có thể được xây dựng sau khi xây dựng máy in và khi dân số đạt 4 người, sẽ làm tăng sản lượng chuông tự do. +model.building.printingPress.name=Máy in +model.building.printingPress.description=Máy in, có thể được nâng cấp thành máy in báo khi dân số đạt 4 người, giúp tăng sản lượng chuông tự do của thuộc địa. +model.building.rumDistillery.name=Nhà máy chưng cất rượu rum +model.building.rumDistillery.description=Ngôi nhà của người chưng cất rượu, có thể được nâng cấp thành nhà máy chưng cất rượu rum, được sử dụng để sản xuất rượu rum từ đường. Khi Adam Smith gia nhập Quốc hội Lục địa và dân số thuộc địa đạt ít nhất 8 người, nhà máy chưng cất rượu rum có thể được thay thế bằng nhà máy sản xuất rượu rum. +model.building.rumFactory.name=Nhà máy lông thú +model.building.rumFactory.description=Nhà máy sản xuất xì gà, vốn không thể nâng cấp, được sử dụng để sản xuất xì gà từ thuốc lá. Nhà máy sản xuất xì gà giúp tăng sản lượng xì gà. +model.building.schoolhouse.name=Trường học +model.building.schoolhouse.description=Một thuộc địa có dân số ít nhất 4 người có thể xây dựng một trường học, cho phép một số thợ thủ công lành nghề dạy nghề cho những người dân thuộc địa chưa có kỹ năng. Ngay khi dân số đạt 8 người, trường học có thể được nâng cấp thành trường cao đẳng, nơi hai người dân thuộc địa có thể dạy thêm các nghề khác. Khi dân số đạt 10 người, trường cao đẳng có thể được thay thế bằng trường đại học, nơi ba người dân thuộc địa có thể dạy tất cả các nghề. Trường cao đẳng cho phép giảng dạy 2 kỹ năng. +model.building.shipyard.name=Xưởng đóng tàu +model.building.shipyard.description=Xưởng đóng tàu cho phép người dân thuộc địa sản xuất cá trên các ô biển liền kề với thuộc địa, cho phép sửa chữa tàu và cho phép đóng tàu.\n\nViệc xây dựng xưởng đóng tàu cho phép đóng tàu. +model.building.stables.name=Ổn định +model.building.stables.description=Chuồng trại giúp tăng năng suất tối đa của ngựa bằng cách giảm quy mô đàn. +model.building.stockade.name=Hàng rào +model.building.stockade.description=Công sự, có thể được xây dựng ngay khi dân số thuộc địa đạt 3 người, bảo vệ cư dân khỏi các cuộc tấn công. Công sự có thể được nâng cấp thành pháo đài, cung cấp khả năng bảo vệ tốt hơn và bắn phá các tàu cướp biển và các đơn vị hải quân địch trên các ô biển liền kề. Pháo đài có thể được thay thế bằng pháo đài kiên cố ngay khi dân số đạt 8 người.\n\nXây dựng công sự sẽ tăng khả năng phòng thủ lên 100%. +model.building.textileMill.name=Nhà máy dệt +model.building.textileMill.description=Nhà máy dệt, vốn không thể nâng cấp, được sử dụng để biến bông thành vải. Nhà máy dệt giúp tăng sản lượng vải. +model.building.tobacconistHouse.name=Nhà của người bán thuốc lá +model.building.tobacconistHouse.description=Ngôi nhà của thương nhân buôn lông thú, có thể được nâng cấp thành trạm buôn lông thú, được sử dụng để sản xuất áo khoác từ lông thú. Khi dân số thuộc địa đạt đến 6 người, nó có thể được nâng cấp hơn nữa thành nhà máy sản xuất lông thú, với điều kiện Adam Smith đã gia nhập Quốc hội Lục địa. +model.building.tobacconistShop.name=Cửa hàng bán thuốc lá +model.building.tobacconistShop.description=Trạm buôn bán lông thú, có thể được nâng cấp thành nhà máy sản xuất lông thú, được sử dụng để sản xuất áo khoác từ lông thú. Khi dân số thuộc địa đạt đến 6 người, nó có thể được nâng cấp hơn nữa thành nhà máy sản xuất lông thú, với điều kiện Adam Smith đã gia nhập Quốc hội Lục địa. Trạm buôn bán lông thú giúp tăng sản lượng áo khoác. +model.building.townHall.name=Thị sảnh +model.building.townHall.description=Tòa thị chính, không thể nâng cấp, cung cấp nơi làm việc cho tối đa ba người dân thuộc địa sản xuất chuông tự do. Hiệu quả của nó có thể được tăng cường bằng cách xây dựng một xưởng in và một tờ báo. +model.building.university.name=Đại học +model.building.university.description=Một thuộc địa có dân số ít nhất 4 người có thể xây dựng một trường học, cho phép một số thợ thủ công lành nghề dạy nghề cho những người dân thuộc địa chưa có kỹ năng. Ngay khi dân số đạt 8 người, trường học có thể được nâng cấp thành trường cao đẳng, nơi hai người dân thuộc địa có thể dạy thêm các nghề khác. Khi dân số đạt 10 người, trường cao đẳng có thể được thay thế bằng trường đại học, nơi ba người dân thuộc địa có thể dạy tất cả các nghề. Trường cao đẳng cho phép giảng dạy 2 kỹ năng. +model.building.warehouse.name=Nhà kho +model.building.warehouse.description=Kho hàng này lưu trữ đủ loại hàng hóa. Đây là bản nâng cấp đầu tiên của kho, với sức chứa 200 đơn vị cho mỗi loại hàng hóa. Việc xây dựng thêm kho sẽ tăng sức chứa lên 300 đơn vị. +model.building.warehouseExpansion.name=Mở rộng kho hàng +model.building.warehouseExpansion.description=Kho hàng mở rộng này chứa được tất cả các loại hàng hóa. Đây là bản nâng cấp của kho hàng đơn giản, với sức chứa 300 đơn vị cho mỗi loại hàng hóa. +model.building.weaverHouse.name=Nhà của thợ dệt +model.building.weaverHouse.description=Ngôi nhà của người thợ dệt, có thể được nâng cấp thành xưởng dệt, được sử dụng để biến bông thành vải. Nó có thể được nâng cấp thành nhà máy dệt khi dân số của thuộc địa đạt ít nhất 8 người và Adam Smith gia nhập Quốc hội Lục địa. +model.building.weaverShop.name=Cửa hàng của thợ dệt +model.building.weaverShop.description=Ngôi nhà của người thợ dệt, có thể được nâng cấp thành xưởng dệt, được sử dụng để biến bông thành vải. Nó có thể được nâng cấp thành nhà máy dệt khi dân số của thuộc địa đạt ít nhất 8 người và Adam Smith gia nhập Quốc hội Lục địa. +model.disaster.bankruptcy.name=Phá sản +model.disaster.blizzard.name=Bão tuyết +model.disaster.brushfire.name=Cháy rừng +model.disaster.disease.name=Bệnh +model.disaster.drought.name=Hạn hán +model.disaster.earthquake.name=Động đất +model.disaster.flood.name=Lụt +model.disaster.hurricane.name=Bão +model.disaster.landslide.name=Sạt lở đất +model.disaster.sandstorm.name=Bão cát +model.disaster.stormsurge.name=sóng thần +model.disaster.tornado.name=Bão lốc +model.disaster.effect.damagedUnit.name=Thiệt hại đối với các đơn vị +model.disaster.effect.damagedUnit=%unit% đã bị hư hỏng. +model.disaster.effect.lossOfBuilding.name=Mất mát các tòa nhà +model.disaster.effect.lossOfBuilding=%building% đã bị phá hủy. +model.disaster.effect.lossOfBuildingProduction.name=Thiệt hại do sản xuất xây dựng +model.disaster.effect.lossOfBuildingProduction=Các công trình bị hư hại. Áp dụng các hình phạt về sản xuất. +model.disaster.effect.lossOfGoods.name=Thiệt hại hàng hóa +model.disaster.effect.lossOfGoods=%goods% bị mất. +model.disaster.effect.lossOfMoney.name=Mất tiền +model.disaster.effect.lossOfMoney=Lượng vàng bị mất %amount% . +model.disaster.effect.lossOfTileProduction.name=Sản xuất gạch thấp +model.disaster.effect.lossOfTileProduction=Các công trình bị hư hại. Áp dụng các hình phạt về sản xuất. +model.disaster.effect.lossOfUnit.name=Mất mát đơn vị +model.disaster.effect.lossOfUnit=%unit% đã bị mất. +model.event.boycottsLifted.name=Các cuộc tẩy chay được dỡ bỏ. +model.event.declareIndependence.name=Tuyên Bố Độc Lập +model.event.freeBuilding.name=Các tòa nhà được cung cấp miễn phí. +model.event.increaseSonsOfLiberty.name=Tâm lý nổi loạn gia tăng +model.event.movementChange.name=Sự chuyển động đã thay đổi +model.event.newRecruits.name=Tuyển dụng người châu Âu thay đổi +model.event.resetBannedMissions.name=Người bản địa sẽ lại chào đón các nhà truyền giáo của bạn. +model.event.resetNativeAlarm.name=Báo động gốc đã bị xóa +model.event.seeAllColonies.name=Tất cả các thuộc địa đều trở nên rõ ràng. +model.event.spanishSuccession.name=Kết thúc Chiến tranh Kế vị Tây Ban Nha +model.foundingFather.adamSmith.description=Cho phép xây dựng nhà máy. +model.foundingFather.adamSmith.text=Được biết đến nhiều hơn với danh hiệu Cha đẻ của Kinh tế học hiện đại, Smith đã viết nhiều tác phẩm liên quan đến lý thuyết kinh tế, trong đó nổi tiếng nhất là "Sự giàu có của các quốc gia". +model.foundingFather.jacobFugger.description=Tất cả các lệnh tẩy chay hiện hành đều bị bãi bỏ. +model.foundingFather.jacobFugger.text=Một thương gia và chủ ngân hàng người Đức cực kỳ giàu có. Ông đã tích lũy được khối tài sản khổng lồ thông qua các mối quan hệ hợp tác gia đình và nắm giữ cổ phần trong ngành công nghiệp khai thác mỏ. +model.foundingFather.peterMinuit.description=Người dân bản địa không còn đòi tiền bồi thường cho đất đai của họ nữa. +model.foundingFather.peterMinuit.text=Ông đã mua vùng đất sau này được gọi là đảo Manhattan từ người bản địa với giá khoảng 60 guilder Hà Lan. Sau này, ông cũng đã khai hoang vùng vịnh Delaware. +model.foundingFather.peterStuyvesant.description=Việc xây dựng các nhà hải quan trở nên khả thi. +model.foundingFather.peterStuyvesant.text=Ông được bổ nhiệm làm Toàn quyền của Tân Hà Lan, vùng đất này sau cuộc xâm lược của Anh mà ông không thể ngăn chặn đã trở thành New York. +model.foundingFather.janDeWitt.description=Việc giao thương với các thuộc địa nước ngoài trở nên khả thi và nhiều thông tin hơn về các đối thủ thuộc địa được công bố. +model.foundingFather.janDeWitt.text=De Witt là một chính khách vĩ đại của Hà Lan. Ông đại diện cho giới thương gia và khuyến khích công nghiệp và thương mại. Ông cũng đã đàm phán một số hiệp ước quan trọng giúp Hà Lan chấm dứt chiến tranh với Anh. +model.foundingFather.ferdinandMagellan.description=Tốc độ di chuyển của tàu hải quân tăng thêm 1 và thời gian di chuyển đến/từ châu Âu/châu Mỹ được rút ngắn. +model.foundingFather.ferdinandMagellan.text=Một trong những nhà thám hiểm vĩ đại nhất từng đi vòng quanh thế giới. Magellan là người đầu tiên đi vòng quanh trái đất và vượt qua Thái Bình Dương. +model.foundingFather.franciscoDeCoronado.description=Tất cả các thuộc địa hiện có đều hiển thị trên bản đồ. +model.foundingFather.franciscoDeCoronado.text=Là nhà thám hiểm châu Âu đầu tiên nhìn thấy Grand Canyon. Mặc dù ông không bao giờ tìm thấy những thành phố vàng mà mình tìm kiếm, nhưng việc ông lập bản đồ khu vực ngày nay gọi là Tây Nam Hoa Kỳ rất quan trọng đối với các cuộc thám hiểm sau này. +model.foundingFather.hernandoDeSoto.description=Việc khám phá những lời đồn đại về Thành phố Mất tích không bao giờ mang lại kết quả tiêu cực và tất cả các đơn vị trên bộ đều có tầm nhìn mở rộng. +model.foundingFather.hernandoDeSoto.text=Ông là người châu Âu đầu tiên khám phá Florida và vùng đông nam Hoa Kỳ. Ông cũng đóng vai trò quan trọng trong các cuộc chinh phục Trung Mỹ. +model.foundingFather.henryHudson.description=Tăng sản lượng của tất cả những người săn bắt thú lấy lông lên 100%. +model.foundingFather.henryHudson.text=Nhà hàng hải người Anh, người đã khám phá và lập bản đồ một khu vực rộng lớn ở phía đông bắc lục địa Bắc Mỹ. Nhiều tuyến đường thủy trong khu vực đó được đặt theo tên ông. Mục tiêu ban đầu của ông là tìm ra Hành lang Tây Bắc nổi tiếng. +model.foundingFather.laSalle.description=Cung cấp cho tất cả các thuộc địa hiện tại và tương lai một hàng rào phòng thủ khi dân số của chúng đạt đến 3 người. +model.foundingFather.laSalle.text=Là người châu Âu đầu tiên đi dọc sông Mississippi, de La Salle có nhiệm vụ thiết lập nhiều trạm giao dịch dọc theo bờ sông. Sau này, ông tuyên bố toàn bộ lưu vực sông là Louisiana để vinh danh nhà vua Pháp. Về sau, ông còn khám phá một số hồ trong Ngũ Đại Hồ. +model.foundingFather.hernanCortes.description=Các khu định cư bản địa bị chinh phục luôn mang lại kho báu (và với số lượng lớn hơn), và các chiến thuyền của nhà vua vận chuyển chúng miễn phí. +model.foundingFather.hernanCortes.text=Người chiến thắng Tây Ban Nha nổi tiếng lật đổ Đế chế Aztec và tuyên bố Mexico là nước Tây Ban Nha. +model.foundingFather.georgeWashington.description=Bất kỳ binh lính hoặc kỵ binh nào giành chiến thắng trong trận chiến sẽ tự động được nâng cấp lên cấp độ tiếp theo. +model.foundingFather.georgeWashington.text=Tướng Washington đã lãnh đạo quân đội thuộc địa giành chiến thắng trước quân Anh, mang lại độc lập cho các thuộc địa. Chiến thắng này và tài lãnh đạo của ông đã giúp ông được bổ nhiệm làm Tổng thống đầu tiên của quốc gia mới. +model.foundingFather.paulRevere.description=Khi một thuộc địa không có binh lính đứng vững bị tấn công, một người thuộc địa tự động lấy bất kỳ khẩu súng đạn nào được tích trữ và bảo vệ. +model.foundingFather.paulRevere.text=Người kỵ sĩ nổi tiếng thời thuộc địa Mỹ đã cưỡi ngựa phi qua vùng nông thôn để cảnh báo dân chúng rằng binh lính Anh đang đến. Ông bị bắt trong lúc phi ngựa và sau đó được thả khi những kẻ bắt giữ ông tin rằng họ đang gặp nguy hiểm nghiêm trọng và tù nhân của họ có thể làm chậm bước tiến của họ. +model.foundingFather.francisDrake.description=Tăng sức mạnh chiến đấu của tất cả các hải tặc lên 50%. +model.foundingFather.francisDrake.text=Drake, một thuyền trưởng người Anh vĩ đại, là người Anh đầu tiên đi vòng quanh thế giới và là anh hùng trong các trận chiến chống lại hạm đội Tây Ban Nha. +model.foundingFather.johnPaulJones.description=Một tàu khu trục nhỏ sẽ được bổ sung vào hải quân thuộc địa của bạn (miễn phí). +model.foundingFather.johnPaulJones.text=Được ca ngợi là một thuyền trưởng vĩ đại ở Mỹ, Jones đã thốt lên câu nói nổi tiếng "Thưa ngài, tôi vẫn chưa bắt đầu cuộc chiến" khi giao chiến với người Anh trên biển. Sau đó, ông chứng kiến con tàu của mình chìm xuống đáy đại dương từ boong của một tàu Anh. +model.foundingFather.thomasJefferson.description=Tăng sản xuất Liberty Bell ở các thuộc địa 50%. +model.foundingFather.thomasJefferson.text=Là một tiếng nói mạnh mẽ của lòng yêu nước, Jefferson được ghi nhận là người đã viết Tuyên ngôn Độc lập. Sau này ông trở thành Tổng thống thứ 3 của Hoa Kỳ. +model.foundingFather.pocahontas.description=Mọi căng thẳng giữa bạn và người bản địa đều được loại bỏ và sự báo động của người Ấn Độ giảm đi một nửa tốc độ. +model.foundingFather.pocahontas.text=Bà là người hòa giải giữa những người định cư đầu tiên ở Jamestown và người bản địa. Bà được ghi nhận là người đã gửi lương thực và các nhu yếu phẩm khác cho những người dân thuộc địa đang đói khổ trong thời kỳ khó khăn. Sau đó, bà cải đạo sang Cơ đốc giáo và kết hôn với một người Anh. +model.foundingFather.thomasPaine.description=Tăng sản lượng Chuông Tự do ở các thuộc địa lên bằng giá trị của mức thuế hiện hành. +model.foundingFather.thomasPaine.text=Ông đã truyền cảm hứng cho những người dân thuộc địa bằng ngòi bút của mình theo lời kêu gọi của Benjamin Franklin. Ông đã xuất bản một cuốn sách nhỏ, "Lẽ thường", hướng dẫn tư tưởng của những người yêu nước trên khắp các thuộc địa. +model.foundingFather.simonBolivar.description=Số lượng thành viên của Hội Con Trai Tự Do tại tất cả các chi hội hiện có tăng thêm 20%. +model.foundingFather.simonBolivar.text=Ông được nhớ đến như một nhà lãnh đạo vĩ đại trong cuộc đấu tranh giành độc lập của Nam Mỹ khỏi Tây Ban Nha. Bolivar đã giải phóng vùng đất ngày nay là Venezuela và sau đó trở thành Tổng thống đầu tiên của nước này. +model.foundingFather.benjaminFranklin.description=Các cuộc chiến tranh nước ngoài của Hoàng gia Anh không còn ảnh hưởng đến các mối quan hệ ở Tân Thế giới và người châu Âu ở Tân Thế giới luôn đề nghị hòa bình trong các cuộc đàm phán. +model.foundingFather.benjaminFranklin.text=Là một người đóng góp quan trọng vào Tuyên ngôn Độc lập, Franklin là một trong những tiếng nói quan trọng của cuộc Cách mạng. Ông đã đi lại rộng khắp giữa châu Âu và các thuộc địa, và giành được sự ủng hộ của người Pháp trong cuộc chiến. +model.foundingFather.williamBrewster.description=Không còn tội phạm hay người hầu nào xuất hiện ở bến tàu nữa, và bạn có thể chọn người nhập cư nào trong danh sách tuyển dụng để chuyển đến bến tàu. +model.foundingFather.williamBrewster.text=Brewster là thủ lĩnh Thanh giáo của thuộc địa Plymouth ở New England. +model.foundingFather.williamPenn.description=Năng suất lai giống ở tất cả các đàn tăng 50%. +model.foundingFather.williamPenn.text=Là bạn thân của Công tước xứ York, Penn được ban tặng vùng đất chủ yếu là Pennsylvania, Delaware và New Jersey. Ông đã cai quản thuộc địa của người Quaker trong vài năm để tạo ra một nơi trú ẩn an toàn cho những người cùng tín ngưỡng. +model.foundingFather.fatherJeanDeBrebeuf.description=Tất cả các nhà truyền giáo đều hoạt động như những chuyên gia. +model.foundingFather.fatherJeanDeBrebeuf.text=Ông kết bạn với người Huron và cải đạo nhiều người sang Cơ Đốc giáo. Ông qua đời dưới tay người Iroquois, những người cuối cùng đã đánh bại kẻ thù của họ, người Huron. +model.foundingFather.juanDeSepulveda.description=Tăng 20% khả năng dân cư của một khu định cư thổ dân bị chinh phục sẽ "cải đạo" và gia nhập thuộc địa của bạn. +model.foundingFather.juanDeSepulveda.text=Một nhà thần học người Tây Ban Nha, người đã lên tiếng ủng hộ việc chinh phục đất đai của người da đỏ và cưỡng bức truyền đạo cho người bản địa. +model.foundingFather.bartolomeDeLasCasas.description=Tất cả những người Ấn Độ cải đạo hiện có đều được chuyển đổi thành người định cư tự do. +model.foundingFather.bartolomeDeLasCasas.text=Một linh mục Công giáo đã đi khắp vùng Indies để cải đạo người bản địa và chỉ trích Tây Ban Nha vì cách đối xử tàn bạo với họ. +model.foundingFather.trade=Tuyến đường +model.foundingFather.exploration=Cách khám mạch +model.foundingFather.military=Quân sự +model.foundingFather.political=Thuộc về chính trị +model.foundingFather.religious=Tôn giáo +model.goods.bells.name={{số nhiều: %amount% |một=Chuông|những=Chuông khác|mặc định=Chuông}} +model.goods.bells.description=Những chiếc chuông tượng trưng cho khát vọng độc lập của những người thuộc địa. +model.goods.bells.workAs=Làm việc với tư cách là Chính khách %claim% ( %amount% Chuông) +model.goods.bells.workingAs=Một nhà nước +model.goods.cigars.name={{số nhiều: %amount% |một=Xì gà|khác=Xì gà|mặc định=Xì gà}} +model.goods.cigars.description=Xì gà được làm từ thuốc lá. Là mặt hàng xa xỉ, chúng có giá rất cao. +model.goods.cigars.workAs=Làm việc với tư cách là người bán thuốc lá %claim% ( %amount% Xì gà) +model.goods.cigars.workingAs=một cửa hàng bán thuốc lá +model.goods.cloth.name={{số nhiều: %amount% |một=Xì gà|khác=Xì gà|mặc định=Xì gà}} +model.goods.cloth.description=Vải được làm từ bông. +model.goods.cloth.workAs=Làm việc với tư cách là Thợ dệt %claim% ( %amount% Vải) +model.goods.cloth.workingAs=một người thợ dệt +model.goods.coats.name={{số nhiều: %amount% |một=Xì gà|khác=Xì gà|mặc định=Xì gà}} +model.goods.coats.description=Áo khoác được làm từ lông thú. +model.goods.coats.workAs=Làm việc với tư cách là Thợ dệt %claim% ( %amount% Vải) +model.goods.coats.workingAs=một thương nhân buôn lông thú +model.goods.cotton.name={{số nhiều: %amount% |một=Xì gà|khác=Xì gà|mặc định=Xì gà}} +model.goods.cotton.description=Bông có thể được dùng để sản xuất vải, và vải có giá thành cao hơn. +model.goods.cotton.workAs=Làm việc với tư cách là người trồng bông %claim% ( %amount% Bông) +model.goods.cotton.workingAs=Người trồng bông +model.goods.crosses.name={{số nhiều: %amount% |một=Xì gà|khác=Xì gà|mặc định=Xì gà}} +model.goods.crosses.description=Những cây thánh giá tượng trưng cho tình trạng bất ổn tôn giáo ở châu Âu. +model.goods.crosses.workAs=Làm việc với tư cách là Thợ dệt %claim% ( %amount% Vải) +model.goods.crosses.workingAs=một nhà thuyết giáo +model.goods.fish.name={{số nhiều: %amount% |một=Cá|những con cá khác|mặc định=Cá}} +model.goods.fish.description=Cá sẽ tự động được chuyển hóa thành thức ăn. +model.goods.fish.workAs=Làm việc với tư cách là Chính khách %claim% ( %amount% Chuông) +model.goods.fish.workingAs=một ngư dân +model.goods.food.name={{số nhiều: %amount% |một=Cá|những con cá khác|mặc định=Cá}} +model.goods.food.description=Thức ăn rất cần thiết để nuôi sống dân thuộc địa và nhân giống ngựa. Một dân thuộc địa mới sẽ ra đời khi thuộc địa có từ 200 đơn vị thức ăn trở lên. +model.goods.food.workAs=Làm việc với tư cách là Thợ dệt %claim% ( %amount% Vải) +model.goods.food.workingAs=Một nông dân +model.goods.furs.name={{số nhiều: %amount% |một=Cá|những con cá khác|mặc định=Cá}} +model.goods.furs.description=Lông của động vật có thể được dùng để sản xuất áo khoác lông. +model.goods.furs.workAs=Làm việc với tư cách là Thợ dệt %claim% ( %amount% Vải) +model.goods.furs.workingAs=một thương nhân buôn lông thú +model.goods.grain.name={{số nhiều: %amount% |một=Xì gà|khác=Xì gà|mặc định=Xì gà}} +model.goods.grain.description=Các loại ngũ cốc như lúa mì, gạo và ngô là nguồn thực phẩm quan trọng nhất cho người dân thuộc địa của bạn. +model.goods.grain.workAs=Làm việc với tư cách là Thợ dệt %claim% ( %amount% Vải) +model.goods.grain.workingAs=Một nông dân +model.goods.hammers.name={{số nhiều: %amount% |một=Xì gà|khác=Xì gà|mặc định=Xì gà}} +model.goods.hammers.description=Những chiếc búa tượng trưng cho công việc xây dựng được thực hiện trong các thuộc địa của bạn. +model.goods.hammers.workAs=Công việc thợ mộc %claim% ( %amount% búa) +model.goods.hammers.workingAs=Thợ Đóng Đồ Gỗ +model.goods.lumber.name={{số nhiều: %amount% |một=Xì gà|khác=Xì gà|mặc định=Xì gà}} +model.goods.lumber.description=Gỗ là nguyên liệu cần thiết để xây dựng các công trình và một số vật dụng nhất định, chẳng hạn như tàu thuyền. +model.goods.lumber.workAs=Công việc thợ đốn gỗ %claim% ( %amount% Gỗ) +model.goods.lumber.workingAs=một người đốn gỗ +model.goods.meat.name={{số nhiều: %amount% |một=Xì gà|khác=Xì gà|mặc định=Xì gà}} +model.goods.meat.description=Thịt, chẳng hạn như thịt bò, thịt lợn và thịt nai, là một nguồn protein quan trọng. +model.goods.meat.workAs=Làm việc với tư cách là Chính khách %claim% ( %amount% Chuông) +model.goods.meat.workingAs=một Thợ săn +model.goods.muskets.name={{số nhiều: %amount% |một=Xì gà|khác=Xì gà|mặc định=Xì gà}} +model.goods.muskets.description=Súng hỏa mai là trang bị cần thiết cho các đơn vị bộ binh và kỵ binh. +model.goods.muskets.workAs=Làm việc với tư cách là Chính khách %claim% ( %amount% Chuông) +model.goods.muskets.workingAs=một thợ sửa súng +model.goods.ore.name={{số nhiều: %amount% |một=Cá|những con cá khác|mặc định=Cá}} +model.goods.ore.description=Quặng là nguyên liệu cần thiết để sản xuất công cụ, và công cụ có rất nhiều công dụng. +model.goods.ore.workAs=Làm việc với tư cách là Thợ dệt %claim% ( %amount% Vải) +model.goods.ore.workingAs=một người khai thác quặng +model.goods.rum.name={{số nhiều: %amount% |một=Xì gà|khác=Xì gà|mặc định=Xì gà}} +model.goods.rum.description=Rượu rum là một loại rượu mạnh được làm từ mía. Là một mặt hàng xa xỉ, nó có giá rất cao. +model.goods.rum.workAs=Làm việc với tư cách là người chưng cất rượu %claim% ( %amount% Rum) +model.goods.rum.workingAs=một nhà máy chưng cất +model.goods.silver.name={{số nhiều: %amount% |một=Xì gà|khác=Xì gà|mặc định=Xì gà}} +model.goods.silver.description=Bạc là một kim loại quý có giá trị cao. +model.goods.silver.workAs=Làm việc với tư cách là Thợ dệt %claim% ( %amount% Vải) +model.goods.silver.workingAs=Một thợ khai thác bạc +model.goods.sugar.name={{số nhiều: %amount% |one=Đường|other=Đường|default=Đường}} +model.goods.sugar.description=Đường là một chất tạo ngọt hiệu quả và cũng có thể được dùng để sản xuất rượu rum, loại rượu có giá thành cao hơn. +model.goods.sugar.workAs=Làm việc với tư cách là Thợ dệt %claim% ( %amount% Vải) +model.goods.sugar.workingAs=một người trồng mía +model.goods.tobacco.name={{số nhiều: %amount% |một=Xì gà|khác=Xì gà|mặc định=Xì gà}} +model.goods.tobacco.description=Thuốc lá có thể được hút hoặc dùng để sản xuất xì gà, từ đó thu được giá thành cao hơn. +model.goods.tobacco.workAs=Làm việc với tư cách là người trồng bông %claim% ( %amount% Bông) +model.goods.tobacco.workingAs=Người trồng thuốc lá +model.goods.tools.name={{số nhiều: %amount% |một=Cá|những con cá khác|mặc định=Cá}} +model.goods.tools.description=Công cụ rất cần thiết để trang bị cho các đơn vị tiên phong, cũng như để xây dựng các công trình tiên tiến và một số đơn vị nhất định, chẳng hạn như tàu thuyền. Chúng cũng có thể được sử dụng để sản xuất súng hỏa mai. +model.goods.tools.workAs=Làm việc với tư cách là Chính khách %claim% ( %amount% Chuông) +model.goods.tools.workingAs=một thợ rèn +model.goods.horses.name={{số nhiều: %amount% |một=Ngựa|khác=Những con ngựa|mặc định=Những con ngựa}} +model.goods.horses.description=Ngựa rất cần thiết để tạo ra các đơn vị trinh sát và kỵ binh. Để nhân giống ngựa trong thuộc địa, bạn cần một số ngựa và ít nhất một đơn vị thức ăn gia súc mỗi lượt. +model.goods.tradeGoods.name={{số nhiều: %amount% |một=Hàng hóa thương mại|khác=Hàng hóa thương mại|mặc định=Hàng hóa thương mại}} +model.goods.tradeGoods.description=Hàng hóa thương mại chỉ được sản xuất ở châu Âu và được sử dụng để giao dịch với người bản địa. +model.improvement.clearForest.action=Chặt phá rừng +model.improvement.clearForest.name=Định dạng rõ ràng +model.improvement.clearForest.occupationString=C +model.improvement.fishBonusLand.description=Thưởng đánh bắt cá nhờ khu vực đất liền gần đó +model.improvement.fishBonusLand.name=Thưởng câu cá (vùng ven biển) +model.improvement.fishBonusRiver.description=Tặng thưởng cá vì một con sông +model.improvement.fishBonusRiver.name=Thưởng câu cá (sông) +model.improvement.plow.action=Cánh đồng cày +model.improvement.plow.description=Đã cày +model.improvement.plow.name=thấp +model.improvement.plow.occupationString=P +model.improvement.river.description=Sông +model.improvement.river.name=Dòng sông +model.improvement.road.action=Xây dựng đường +model.improvement.road.description=Đường +model.improvement.road.name=Đường +model.improvement.road.occupationString=R +model.limit.independence.coastalColonies.name=Giới hạn thuộc địa ven biển +model.limit.independence.coastalColonies.description=Bạn cần ít nhất %limit% thuộc địa ven biển {{số nhiều: %limit% |một=thuộc địa|những=thuộc địa khác}} để tuyên bố độc lập. +model.limit.independence.rebels.name=Giới hạn nổi loạn +model.limit.independence.rebels.description=Ít nhất %limit% % số người dân thuộc địa của bạn phải ủng hộ nền độc lập. +model.limit.independence.year.name=Giới hạn năm +model.limit.independence.year.description=Bạn phải tuyên bố độc lập trước khi kết thúc %limit% . +model.limit.wagonTrains.name=Giới hạn đoàn xe +model.limit.wagonTrains.description=Số lượng tàu chở xe của bạn không được vượt quá số lượng của các thuộc địa của bạn. +model.nation.apache.name=Apache +model.nation.arawak.name=Arawak +model.nation.aztec.name=Người Aztec +model.nation.cherokee.name=Cherokee +model.nation.inca.name=Inca +model.nation.iroquois.name=Người Iroquois +model.nation.sioux.name=Người Sioux +model.nation.tupi.name=Tupi +model.nation.unknownEnemy.name=Kẻ thù +model.nation.danish.name={{tag:|country=Đan Mạch|people=Đan Mạch|default=Đan Mạch}} +model.nation.danish.newLandName=Tân Đan Mạch +model.nation.danishREF.name=Lực lượng Viễn chinh Hoàng gia +model.nation.dutch.name={{tag:|country=Hà Lan|people=Hà Lan|default=Hà Lan}} +model.nation.dutch.newLandName=New Holland +model.nation.dutchREF.name=Lực lượng Viễn chinh Hoàng gia +model.nation.english.name={{tag:|country=England|people=English|default=English}} +model.nation.english.newLandName=New England +model.nation.englishREF.name=Lực lượng Viễn chinh Hoàng gia +model.nation.french.name={{tag:|country=France|people=French|default=French}} +model.nation.french.newLandName=Tân Pháp +model.nation.frenchREF.name=Quy mô của Lực lượng Viễn chinh Hoàng gia +model.nation.portuguese.name={{tag:|country=Portugal|people=Portuguese|default=Portuguese}} +model.nation.portuguese.newLandName=Vùng đất Thánh Giá +model.nation.portugueseREF.name=Lực lượng Viễn chinh Hoàng gia +model.nation.russian.name={{tag:|country=Russia|people=Russian|default=Russian}} +model.nation.russian.newLandName=Nước Nga mới +model.nation.russianREF.name=Lực lượng Viễn chinh Hoàng gia +model.nation.spanish.name={{tag:|country=Đan Mạch|people=Đan Mạch|default=Đan Mạch}} +model.nation.spanish.newLandName=Tân Tây Ban Nha +model.nation.spanishREF.name=Quy mô của Lực lượng Viễn chinh Hoàng gia +model.nation.swedish.name={{tag:|country=Đan Mạch|people=Đan Mạch|default=Đan Mạch}} +model.nation.swedish.newLandName=Thụy Điển mới +model.nation.swedishREF.name=Lực lượng Viễn chinh Hoàng gia +model.nationType.agriculture.name=Nông nghiệp +model.nationType.agriculture.shortDescription=Sản xuất nhiều lương thực hơn +model.nationType.apache.name=Apache +model.nationType.apache.description=Quốc gia Apache +model.nationType.arawak.name=Arawak +model.nationType.arawak.description=Dân tộc Arawak +model.nationType.aztec.name=Người Aztec +model.nationType.aztec.description=Quốc gia Aztec +model.nationType.building.name=Tòa nhà +model.nationType.building.shortDescription=Sản xuất nhiều vật liệu xây dựng hơn +model.nationType.cherokee.name=Cherokee +model.nationType.cherokee.description=Dân tộc Cherokee +model.nationType.conquest.name=Cuộc thi +model.nationType.conquest.shortDescription=Khả năng thuyết phục người bản địa cao hơn +model.nationType.cooperation.name=Sự hợp tác +model.nationType.cooperation.shortDescription=Người bản địa ít lo lắng hơn. +model.nationType.default.name=Không có +model.nationType.default.shortDescription=Không có lợi thế quốc gia +model.nationType.furTrapping.name=Bẫy thú lấy lông +model.nationType.furTrapping.shortDescription=Sản xuất nhiều lông thú và áo khoác hơn. +model.nationType.immigration.name=Nhập cư +model.nationType.immigration.shortDescription=Tạo ra số lượng người nhập cư lớn hơn +model.nationType.inca.name=Inca +model.nationType.inca.description=Quốc gia Inca +model.nationType.iroquois.name=Người Iroquois +model.nationType.iroquois.description=Quốc gia Iroquois +model.nationType.naval.name=Hải quân +model.nationType.naval.shortDescription=Các đơn vị hải quân có tầm hoạt động xa hơn. +model.nationType.ref.name=Lực lượng Viễn chinh Hoàng gia +model.nationType.ref.shortDescription=Quy mô của Lực lượng Viễn chinh Hoàng gia +model.nationType.sioux.name=Người Sioux +model.nationType.sioux.description=Quốc gia Sioux +model.nationType.trade.name=Tuyến đường +model.nationType.trade.shortDescription=Giá cả ưu đãi hơn +model.nationType.tupi.name=Tupi +model.nationType.tupi.description=Dân tộc Tupi +model.resource.cotton.name=Bông +model.resource.cotton.description=Đất ở vùng thảo nguyên này đặc biệt thích hợp cho việc trồng bông. +model.resource.fish.name=Cá +model.resource.fish.description=Số lượng lớn cá nhỏ thu hút nhiều cá lớn đến địa điểm này, từ đó thu hút những người câu cá đầy nhiệt huyết. +model.resource.furs.name=Lông thú +model.resource.furs.description=Số lượng động vật phong phú trong những khu rừng này thu hút nhiều thợ săn đến tìm kiếm con mồi dễ dàng. +model.resource.game.name=Thú vật +model.resource.game.description=Khu rừng này là nơi sinh sống của nhiều loài động vật, thích hợp cho việc săn bắt để lấy lông hoặc làm thực phẩm. +model.resource.grain.name=Xe lửa +model.resource.grain.description=Cây trồng phát triển rất tốt trên vùng đồng bằng màu mỡ này. +model.resource.lumber.name=Số +model.resource.lumber.description=Khu rừng này có những cây gỗ chắc khỏe, thích hợp để khai thác gỗ. +model.resource.minerals.name=Khoáng chất +model.resource.minerals.description=Vùng đất này rất giàu khoáng sản, và nếu ai kiên nhẫn, họ có thể tìm thấy quặng hoặc thậm chí là bạc. +model.resource.oasis.name=Ốc đảo +model.resource.oasis.description=Ốc đảo giữa sa mạc là một cảnh tượng chào đón đối với tất cả những lữ khách mệt mỏi. +model.resource.ore.name=Quặng +model.resource.ore.description=Mặt đất nứt ra và một mạch quặng lớn lộ ra để khai thác. Chúng chỉ được tìm thấy ở những vùng địa hình đồi núi. +model.resource.silver.name=Bạc +model.resource.silver.description=Ngọn núi này nổi tiếng vì có các mạch bạc, và sẽ giúp các thị trấn lân cận thịnh vượng. +model.resource.sugar.name=Mía +model.resource.sugar.description=Đất ở vùng thảo nguyên này đặc biệt thích hợp cho việc trồng bông. +model.resource.tobacco.name=Thuốc lá +model.resource.tobacco.description=Đất ở vùng thảo nguyên này đặc biệt thích hợp cho việc trồng bông. +model.role.name=Vai trò +model.role.armedBrave.name=Dũng cảm có vũ trang +model.role.cavalry.name=Tội ngựa +model.role.default.name=Mặc định +model.role.dragoon.name=Kỵ binh +model.role.dragoon.noequipment=không có súng hỏa mai +model.role.infantry.name=Bộ binh +model.role.missionary.name=Nhà truyền giáo +model.role.missionary.noequipment=không được ủy nhiệm +model.role.missionary.equipment=Kinh Thánh +model.role.mountedBrave.name=Dũng sĩ cưỡi ngựa +model.role.nativeDragoon.name=Kỵ binh bản địa +model.role.pioneer.name=Người tiên phong +model.role.pioneer.noequipment=Công cụ Bot +model.role.scout.name=Trinh sát +model.role.scout.noequipment=không có ngựa +model.role.soldier.name=Lính +model.role.soldier.noequipment=không có súng hỏa mai +model.role.change.dragoon=Trang bị như lính kỵ binh +model.role.change.missionary=Sứ mệnh truyền giáo +model.role.change.pioneer=Trang bị các công cụ +model.role.change.scout=Trang bị như một trinh sát +model.role.change.default.soldier=Cánh tay +model.role.change.dragoon.default=Tháo dỡ tất cả thiết bị +model.role.change.dragoon.soldier=Xuống ngựa +model.role.change.missionary.default=Hủy bỏ tư cách nhà truyền giáo +model.role.change.missionary.soldier=Cánh tay +model.role.change.pioneer.default=thêm công cụ +model.role.change.pioneer.soldier=Cánh tay +model.role.change.scout.default=Xuống ngựa +model.role.change.scout.soldier=Xuống ngựa và trang bị vũ khí. +model.role.change.soldier.default=Giải giáp +model.settlement.aztec.capital.name=Thành phố Aztec +model.settlement.aztec.name=Thành phố Aztec +model.settlement.aztec.plural=Thành phố +model.settlement.camp.capital.name=Trại +model.settlement.camp.name=Trại +model.settlement.camp.plural=trại +model.settlement.city.capital.name=Thành phố +model.settlement.city.name=Thành phố: +model.settlement.city.plural=Thành phố +model.settlement.colony.capital.name=Thuộc địa +model.settlement.colony.name=Thuộc địa +model.settlement.colony.plural=thuộc địa +model.settlement.default.name=*Mặc định +model.settlement.inca.capital.name=Thành phố Inca +model.settlement.inca.name=Thành phố Inca +model.settlement.inca.plural=thành phố +model.settlement.village.capital.name=Làng +model.settlement.village.name=Làng +model.settlement.village.plural=Làng +model.tile.arctic.name=Bắc cực +model.tile.arctic.description=Vùng Bắc Cực chủ yếu là một đại dương rộng lớn phủ đầy băng, bao quanh là vùng đất đóng băng không có cây cối và không có gì sinh sôi nảy nở. Chúng được tìm thấy gần Bắc Cực và Nam Cực và thường không thể duy trì các quần thể sinh vật. +model.tile.borealForest.name=Rừng phương Bắc +model.tile.borealForest.description=Rừng phương bắc sản xuất ngũ cốc, gỗ, lông thú và một số loại quặng. Chúng được tìm thấy gần các vùng cực và có thể bị chặt phá để tạo ra lãnh nguyên. +model.tile.broadleafForest.name=Cây lá rộng +model.tile.broadleafForest.description=Rừng lá rộng cung cấp ngũ cốc, gỗ, lông thú và một ít bông. Chúng được tìm thấy ở các vĩ độ ôn đới và nhường chỗ cho thảo nguyên khi bị chặt phá. +model.tile.coniferForest.name=Rừng thông +model.tile.coniferForest.description=Rừng lá kim cung cấp ngũ cốc, gỗ xẻ, lông thú và một số loại thuốc lá. Chúng chủ yếu được tìm thấy ở các vĩ độ nhiệt đới và nhường chỗ cho đồng cỏ khi bị chặt phá. +model.tile.desert.name=Sa mạc +model.tile.desert.description=Sa mạc rất khô hạn, lượng mưa rất ít. Mặc dù khan hiếm, sa mạc lại sản xuất ra ngũ cốc, bông và quặng. +model.tile.grassland.name=Đồng cỏ +model.tile.grassland.description=Đồng cỏ là những vùng đất bằng phẳng, trải dài liên tục, phủ đầy cỏ. Chúng thường nằm gần các khu rừng ôn đới ở vùng núi cao hoặc sa mạc ở vùng cận nhiệt đới. Đồng cỏ rất lý tưởng để trồng thuốc lá. Ngoài ra, người ta cũng có thể trồng lương thực ở đó. +model.tile.greatRiver.name=Sông lớn +model.tile.greatRiver.description=Các con sông lớn là những con sông mà tàu thuyền có thể đi lại được. +model.tile.highSeas.name=Biển khơi +model.tile.highSeas.description=Vùng biển khơi là nơi sản sinh ra nhiều cá. Chúng cũng cho phép tàu thuyền của bạn đi lại giữa châu Âu và các vùng khác. +model.tile.hills.name=Đồi +model.tile.hills.description=Các ngọn đồi nhô cao hơn địa hình xung quanh, trong một khu vực giới hạn. Đồi núi cung cấp một lượng lớn quặng, cũng như một ít ngũ cốc. +model.tile.lake.name=Hồ +model.tile.lake.description=Hồ là những vùng nước nội địa. Các thuộc địa được xây dựng liền kề sẽ hưởng lợi từ tài nguyên thiên nhiên của hồ, nhưng có thể khó tiếp cận bằng đường thủy. +model.tile.marsh.name=Đầm lầy +model.tile.marsh.description=Đầm lầy là một loại đất ngập nước, đặc trưng bởi cỏ, cây sậy, lau sậy, cây bồ đề, cây cói và các loại cây thân thảo khác trong môi trường nước nông. Đầm lầy sản xuất một số loại ngũ cốc và thuốc lá, cũng như quặng. Đầm lầy chủ yếu được tìm thấy gần các vùng cực. +model.tile.mixedForest.name=Rừng hỗn hợp +model.tile.mixedForest.description=Rừng hỗn hợp, thường được tìm thấy ở các vĩ độ ôn đới, cung cấp ngũ cốc, gỗ, lông thú và một ít bông. Nếu rừng hỗn hợp bị chặt phá, chúng sẽ trở thành đồng bằng. +model.tile.mountains.name=Núi +model.tile.mountains.description=Dãy núi trải dài trên địa hình xung quanh trong một khu vực hạn chế. Núi thường dốc hơn đồi. Việc đi lại trên núi rất khó khăn và không thể thành lập thuộc địa ở đây. Núi cung cấp lợi thế phòng thủ cao nhưng việc xây dựng công sự không làm tăng thêm lợi thế này. Khai thác mỏ tỏ ra hữu ích cho việc khai thác quặng và bạc. +model.tile.ocean.name=Biển +model.tile.ocean.description=Đại dương là những vùng nước mặn rộng lớn, rất tốt cho việc đánh bắt cá. Số lượng cá tăng lên nhờ sự hiện diện của đất liền và đặc biệt là các cửa sông. +model.tile.plains.name=Văn bản thuần +model.tile.plains.description=Đồng bằng là những vùng đất rộng lớn có địa hình tương đối bằng phẳng, thích hợp hơn cho nông nghiệp. Chúng sản xuất nhiều ngũ cốc, một lượng nhỏ bông và một ít quặng. Đồng bằng thường được tìm thấy ở các vùng ôn đới. +model.tile.prairie.name=Đồng cỏ +model.tile.prairie.description=Thảo nguyên là vùng đất có nhiều cỏ và cây thân thảo, ít cây cối, và thường có khí hậu ôn hòa hoặc ấm áp. Thảo nguyên thích hợp nhất để trồng ngũ cốc và bông. +model.tile.rainForest.name=Rừng mưa +model.tile.rainForest.description=Rừng mưa nhiệt đới cung cấp ngũ cốc, gỗ, lông thú, một số quặng và đường. Chúng được tìm thấy ở vùng nhiệt đới và có thể bị chặt phá để tạo thành đầm lầy. +model.tile.savannah.name=Savannah +model.tile.savannah.description=Ở các vùng thảo nguyên, cỏ và cây cối là hai loại thảm thực vật chiếm ưu thế. Thảo nguyên thường được xem là vùng chuyển tiếp, nằm giữa các vùng rừng hoặc vùng cây cối thưa thớt và các vùng đồng cỏ hoặc sa mạc. Thảo nguyên chủ yếu sản xuất ngũ cốc và đường. +model.tile.scrubForest.name=Rừng cây bụi +model.tile.scrubForest.description=Rừng cây bụi cho phép sản xuất ngũ cốc, gỗ, lông thú, một ít bông và quặng. Nếu bị chặt phá, đất sẽ trở thành sa mạc. Rừng cây bụi thường được tìm thấy ở các vùng ôn đới. +model.tile.swamp.name=Đầm lầy +model.tile.swamp.description=Vùng đất ngập nước nhiệt đới được bao quanh bởi các vùng nước nông. Đầm lầy có tỷ lệ diện tích mặt nước mở lớn hơn và thường sâu hơn đầm lầy than bùn. Đầm lầy cho năng suất ngũ cốc, cũng như một lượng nhỏ đường và quặng. +model.tile.tropicalForest.name=Rừng nhiệt đới +model.tile.tropicalForest.description=Rừng nhiệt đới cung cấp ngũ cốc, gỗ, lông thú và một ít đường. Việc phá rừng nhiệt đới tạo ra thảo nguyên. +model.tile.tundra.name=Đài nguyên +model.unit.veteranSoldier.workingAs=Lính +model.building.locationLabel=Tại %location% +model.indianSettlement.mostHatedNone=Không có +model.messageType.default.name=Thông báo +model.messageType.missingGoods.name=Hàng hóa bị mất +model.messageType.tutorial.name=Hướng dẫn +model.messageType.warning.name=Cảnh báo +model.advantages.none.name=Không Có +model.advantages.fixed.name=Cố Định +model.advantages.selectable.name=Cho Phép Chọn +model.advantages.selectable.shortDescription=Lợi thế quốc gia có thể chọn được và không cần phải khác. +model.nationState.aiOnly.name=máy chơi +model.nationState.available.name=có thể chọn +model.nationState.available.shortDescription=Bạn có thể chơi dưới tư cách quốc gia này +model.nationState.notAvailable.name=không thể chọn +model.player.waitingFor=Đang chờ: %nation% +model.stance.alliance.name=Liên minh +model.stance.ceaseFire.name=Ngừng bắn +model.stance.peace.name=Hòa bình +model.stance.war.name=Chiến tranh +# Fuzzy +model.tile.nearLocation=Gần %location% +model.tradeItem.gold.name=Vàng +model.tradeItem.goods.name=Đồ buôn +model.tradeItem.unit.name=Đơn vị +model.season.autumn.name=Mùa thu +model.season.spring.name=Mùa xuân +# Fuzzy +model.player.stance.alliance.declared=Kính thưa, %nation% này là đồng minh với chúng tôi! +# Fuzzy +error.couldNotLoad=Một lỗi đã xảy ra khi cố gắng tải game này từ file %name%! +# Fuzzy +error.couldNotSave=Một lỗi đã xảy ra khi cố gắng lưu game này thành file %name%! +main.defaultPlayerName=Tên người chơi +armedUnitSettlement.attack=Tấn công +buy.moreGold=Xin hạ giá +# Fuzzy +indianLand.cancel=Rời khỏi đất. +info.autodetectLanguageSelected=Bạn vừa chọn chọn chế độ tự động phát hiện ngôn ngữ. Chức năng này sẽ được kích hoạt lần sau khi bạn khởi động lại trò chơi. +info.newLanguageSelected=Thiết lập ngôn ngữ thành %language% . Bạn sẽ cần phải khởi động lại trò chơi để những thay đổi hoàn toàn có hiệu lực. +scoutColony.attack=Tấn công +scoutSettlement.attack=Tấn công +sell.moreGold=Xin thêm vàng +stopCurrentGame.no=Hủy bỏ +tradeProposition.toBuy=Mua +tradeProposition.toSell=Bán +disbandUnit.yes=Giải tán +exploreLostCityRumour.no=Hãy kệ nó. +info.notYourTurn=Hiện không đến lượt bạn! +colopedia.nation.currentAdvantage=Lợi thế hiện tại: +report.labour.otherUnitType=khác +report.labour.summary=Tóm lược +report.labour.workingAs=Làm +report.labour.workingAsOther=khác +report.highScores.nationType=Lợi thế quốc gia: +report.turn.playerNation=%player%'s {{tag:country|%nation%}} +confirmDeclarationDialog.defaultCountry=Hợp chúng quốc {{tag:country|%nation%}} +negotiationDialog.accept=Nhận +negotiationDialog.add=Thêm +negotiationDialog.cancel=Hủy bỏ +negotiationDialog.clear=Tẩy trống +# Fuzzy +negotiationDialog.demand=Đòi +negotiationDialog.send=Gửi +europePanel.transaction.price=Giá:\t%gold% +europePanel.transaction.purchase=Mua %amount% %goods% với giá %gold% +europePanel.transaction.sale=Bán %amount% %goods% với giá %gold% +europePanel.transaction.tax=-%tax%%:\t%gold% +abandonColony.no=Hủy bỏ +abandonColony.yes=Bỏ rơi +stopServer.no=Hủy bỏ +indianSettlementPanel.indianCapital=Thủ đô %nation% +loadingSavegameDialog.ip=Địa chỉ IP: +mapEditorTransformPanel.majorRiver=Sông lớn +mapEditorTransformPanel.minorRiver=Sông nhỏ +newPanel.getServerList=Lấy danh sách server +newPanel.joinMultiPlayerGame=Tham gia trò chơi nhiều người chơi +newPanel.nationalAdvantages=Lợi Thế Quốc Gia +newPanel.publicServer=Máy chủ công cộng +newPanel.showDifficulty=Tuỳ chỉnh độ khó +newPanel.singlePlayerGame=Người chơi đơn +newPanel.startMultiplayerGame=Bắt đầu trò chơi nhiều người chơi +newPanel.startServerOnPort=Bắt đầu server trên cổng +playersTable.advantage=Lợi thế +playersTable.availability=Chọn người chơi +serverListPanel.gameState=Trạng thái trò chơi +serverListPanel.gameState.0=Mới +serverListPanel.gameState.1=Đang chơi +serverListPanel.gameState.2=Chơi xong +serverListPanel.players=Người chơi +startGamePanel.iAmReady=Sẵn +victory.continue=Chơi tiếp +victory.yes=Thoát +warehouseDialog.export=Xuất khẩu +workProductionPanel.zeroThreshold=Không có sản phẩm tiêu cực diff --git a/scripts/generate-sbom.sh b/scripts/generate-sbom.sh new file mode 100755 index 0000000000..32b045ca6e --- /dev/null +++ b/scripts/generate-sbom.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +set -euo pipefail + +OUT_PATH="${1:-build/sbom.cdx.json}" + +if ! command -v syft >/dev/null 2>&1; then + echo "syft is not installed. See https://github.com/anchore/syft" >&2 + exit 1 +fi + +mkdir -p "$(dirname "$OUT_PATH")" +syft dir:. -o cyclonedx-json > "$OUT_PATH" +echo "SBOM written to $OUT_PATH" diff --git a/scripts/scan-sbom.sh b/scripts/scan-sbom.sh new file mode 100755 index 0000000000..97ff8b382e --- /dev/null +++ b/scripts/scan-sbom.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +set -euo pipefail + +SBOM_PATH="${1:-build/sbom.cdx.json}" + +if ! command -v grype >/dev/null 2>&1; then + echo "grype is not installed. See https://github.com/anchore/grype" >&2 + exit 1 +fi + +if [ ! -f "$SBOM_PATH" ]; then + echo "SBOM not found at $SBOM_PATH. Run ./scripts/generate-sbom.sh first." >&2 + exit 1 +fi + +grype "sbom:$SBOM_PATH" diff --git a/src/net/sf/freecol/FreeCol.java b/src/net/sf/freecol/FreeCol.java index a6478640e3..a7fb8dcee2 100644 --- a/src/net/sf/freecol/FreeCol.java +++ b/src/net/sf/freecol/FreeCol.java @@ -166,6 +166,7 @@ public final class FreeCol { private static final String META_SERVER_ADDRESS = "meta.freecol.org"; private static final int META_SERVER_PORT = 3540; private static final int PORT_DEFAULT = 3541; + private static final byte[] ANY_ADDR = new byte[] { 0, 0, 0, 0 }; private static final String SPLASH_DEFAULT = "splash.jpg"; private static final String TC_DEFAULT = "default"; private static final String RULES_DEFAULT = "freecol"; @@ -276,12 +277,12 @@ public static void main(String[] args) { juc = getJarURLConnection(FreeCol.class); } catch (ClassCastException cce) { juc = null; - System.err.println("Unable to cast class properly: " - + cce.getMessage()); + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Unable to cast class properly: " + + cce.getMessage(), cce); } catch (IOException ioe) { juc = null; - System.err.println("Unable to open class jar: " - + ioe.getMessage()); + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Unable to open class jar: " + + ioe.getMessage(), ioe); } if (juc != null) { try { @@ -289,15 +290,15 @@ public static void main(String[] args) { if (revision != null) { freeColRevision += " (Revision: " + revision + ")"; } - } catch (Exception e) { - System.err.println("Unable to load Manifest: " - + e.getMessage()); + } catch (IOException e) { + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Unable to load Manifest: " + + e.getMessage(), e); } try { splashStream = getDefaultSplashStream(juc); - } catch (Exception e) { - System.err.println("Unable to open default splash: " - + e.getMessage()); + } catch (IOException e) { + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Unable to open default splash: " + + e.getMessage(), e); } } @@ -330,12 +331,9 @@ public static void main(String[] args) { .addAmount("%minMemory%", MEMORY_MIN_IN_MB)); } if (memoryCheck && MEMORY_MAX < SOFT_MEMORY_MIN) { - System.err.println(); - System.err.println(); - System.err.println(Messages.message(StringTemplate.template("main.memoryLow") + if (logger.isLoggable(Level.WARNING)) logger.warning(Messages.message(StringTemplate.template("main.memoryLow") .addAmount("%memory%", MEMORY_MAX) .add("%minMemory%", SOFT_MEMORY_MIN_IN_GB + "G"))); - System.err.println(); } // Having parsed the command line args, we know where the user @@ -354,14 +352,18 @@ public static void main(String[] args) { baseLogger.addHandler(new DefaultHandler(consoleLogging, writer)); for (LogLevel ll : logLevels) ll.buildLogger(); } catch (FreeColException e) { - System.err.println("Logging initialization failure: " + e); + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Logging initialization failure: " + e, e); } // This is overridden by FreeColClient. Thread.setDefaultUncaughtExceptionHandler((Thread thread, Throwable e) -> { - baseLogger.log(Level.WARNING, "Uncaught exception from thread: " + thread, e); + if (baseLogger.isLoggable(Level.WARNING)) { + baseLogger.log(Level.WARNING, "Uncaught exception from thread: " + thread, e); + } if (e instanceof Error) { - e.printStackTrace(); + if (baseLogger.isLoggable(Level.SEVERE)) { + baseLogger.log(Level.SEVERE, "Fatal error from thread: " + thread, e); + } System.exit(1); } }); @@ -378,16 +380,16 @@ public static void main(String[] args) { specialOptions = ClientOptions.getSpecialOptions(); } catch (FreeColException fce) { specialOptions = new HashMap<>(); - logger.log(Level.WARNING, "Special options unavailable", fce); + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Special options unavailable", fce); } - String cLang; + String cLang = specialOptions.get(ClientOptions.LANGUAGE); if (localeArg == null - && (cLang = specialOptions.get(ClientOptions.LANGUAGE)) != null + && cLang != null && !Messages.AUTOMATIC.equalsIgnoreCase(cLang) && setLocale(cLang)) { Locale loc = getLocale(); Messages.loadMessageBundle(loc); - logger.info("Loaded messages for " + loc); + if (logger.isLoggable(Level.INFO)) logger.info("Loaded messages for " + loc); } // Now we have the user mods directory and the locale is now @@ -404,7 +406,7 @@ && setLocale(cLang)) { processSpecialOptions(); // Report on where we are. - logger.info(getConfiguration().toString()); + if (logger.isLoggable(Level.INFO)) logger.info(getConfiguration().toString()); // Ready to specialize into client or server. if (standAloneServer) { @@ -566,32 +568,29 @@ private static void fatal(StringTemplate template) { * @param err The error message to print. */ private static void fatal(String err) { - if (err == null || err.isEmpty()) { - err = "Bogus null fatal error message"; + String message = err; + if (message == null || message.isEmpty()) { + message = "Bogus null fatal error message"; Thread.dumpStack(); } - System.err.println(err); + logger.severe(message); quit(1); } /** - * Just gripe to System.err. + * Just gripe to the logger. * * @param template A {@code StringTemplate} to print. */ private static void gripe(StringTemplate template) { - System.err.println(Messages.message(template)); + if (logger.isLoggable(Level.WARNING)) logger.warning(Messages.message(template)); } /** - * Just gripe to System.err. + * Just gripe to the logger. * * @param key A message key. */ - private static void gripe(String key) { - System.err.println(Messages.message(key)); - } - /** * Log a warning with a stack trace. * @@ -610,7 +609,7 @@ public static void trace(Logger logger, String warn) { * @param args The command-line arguments. * @return The option's parameter. */ - private static String findArg(String option, String[] args) { + private static String findArg(String option, String... args) { for (int i = args.length - 2; i >= 0; i--) { if (option.equals(args[i])) { return args[i+1]; @@ -676,7 +675,7 @@ private static String findArg(String option, String[] args) { * * @param args The command-line arguments. */ - private static void handleArgs(String[] args) { + private static void handleArgs(String... args) { Options options = new Options(); for (String[] o : optionsTable) { String arg = o[3]; @@ -935,7 +934,7 @@ private static void handleArgs(String[] args) { } if (line.hasOption("version")) { - System.out.println("FreeCol " + getVersion()); + if (logger.isLoggable(Level.INFO)) logger.info("FreeCol " + getVersion()); quit(0); } @@ -945,7 +944,7 @@ private static void handleArgs(String[] args) { } } catch (ParseException e) { - System.err.println("\n" + e.getMessage() + "\n"); + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, e.getMessage(), e); usageError = true; } if (usageError) printUsage(options, 1); @@ -979,8 +978,8 @@ public static Specification loadSpecification(FreeColModFile rulesFile, try { if (rulesFile != null) spec = rulesFile.getSpecification(); } catch (IOException|XMLStreamException ex) { - System.err.println("Spec read failed in " + rulesFile.getId() - + ": " + ex.getMessage() + "\n"); + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Spec read failed in " + rulesFile.getId() + + ": " + ex.getMessage(), ex); } if (spec != null) spec.prepare(advantages, difficulty); return spec; @@ -1185,7 +1184,9 @@ private static int selectEuropeanCount(String arg) { setEuropeanCount(n); return n; } - } catch (NumberFormatException nfe) {} + } catch (NumberFormatException nfe) { + if (logger.isLoggable(Level.FINE)) logger.log(Level.FINE, "Invalid European count: " + arg, nfe); + } return -1; } @@ -1218,7 +1219,9 @@ private static boolean setMetaServer(String arg) { int port = -1; try { port = (s.length == 2) ? Integer.parseInt(s[1]) : -1; - } catch (NumberFormatException nfe) {} + } catch (NumberFormatException nfe) { + if (logger.isLoggable(Level.FINE)) logger.log(Level.FINE, "Invalid meta-server port: " + arg, nfe); + } if (s.length != 2 || s[0] == null || "".equals(s[0])) return false; metaServerAddress = s[0]; @@ -1245,7 +1248,7 @@ public static String getName() { */ public static void setName(String name) { FreeCol.name = name; - logger.info("Set FreeCol.name = " + name); + if (logger.isLoggable(Level.INFO)) logger.info("Set FreeCol.name = " + name); } /** @@ -1269,20 +1272,21 @@ public static Locale getLocale() { @SuppressFBWarnings(value="MDM_SETDEFAULTLOCALE", justification="Locale can be reset by user") public static boolean setLocale(String localeArg) { - Locale newLocale = null; - if (localeArg == null) { + String localeSpec = localeArg; + Locale newLocale; + if (localeSpec == null) { newLocale = Locale.getDefault(); } else { - int index = localeArg.indexOf('.'); // Strip encoding if present - if (index > 0) localeArg = localeArg.substring(0, index); - newLocale = Messages.getLocale(localeArg); + int index = localeSpec.indexOf('.'); // Strip encoding if present + if (index > 0) localeSpec = localeSpec.substring(0, index); + newLocale = Messages.getLocale(localeSpec); } - if (newLocale != FreeCol.locale) { + boolean changed = newLocale != FreeCol.locale; + if (changed) { FreeCol.locale = newLocale; Locale.setDefault(newLocale); - return true; } - return false; + return changed; } /** @@ -1319,7 +1323,7 @@ public static int getServerPort() { */ public static InetAddress getServerName() { try { - return (serverAddress == null) ? InetAddress.getByName("0.0.0.0") : serverAddress; + return (serverAddress == null) ? InetAddress.getByAddress(ANY_ADDR) : serverAddress; } catch (UnknownHostException e) { return Inet4Address.getLoopbackAddress(); } @@ -1469,7 +1473,9 @@ private static void setWindowSize(String arg) { try { windowSize = new Dimension(Integer.parseInt(xy[0]), Integer.parseInt(xy[1])); - } catch (NumberFormatException nfe) {} + } catch (NumberFormatException nfe) { + if (logger.isLoggable(Level.FINE)) logger.log(Level.FINE, "Invalid window size: " + arg, nfe); + } } } } @@ -1514,12 +1520,10 @@ public static StringTemplate errorFromException(Exception ex, return ((FreeColUserMessageException) ex).getStringTemplate(); } - String msg; - return (ex == null || (msg = ex.getMessage()) == null) - ? fallback - : (Messages.containsKey(msg)) - ? StringTemplate.template(msg) - : (FreeColDebugger.isInDebugMode(FreeColDebugger.DebugMode.MENUS)) + String msg = (ex == null) ? null : ex.getMessage(); + if (msg == null) return fallback; + if (Messages.containsKey(msg)) return StringTemplate.template(msg); + return (FreeColDebugger.isInDebugMode(FreeColDebugger.DebugMode.MENUS)) ? StringTemplate.name(msg) : fallback; } @@ -1617,9 +1621,10 @@ private static SplashScreen createSplashScreen() { if (splashStream != null) { try { final GraphicsDevice defaultScreenDevice = Utils.getGoodGraphicsDevice(); + if (defaultScreenDevice == null) return null; splashScreen = new SplashScreen(defaultScreenDevice, splashStream); splashScreen.setVisible(true); - } catch (Exception e) { + } catch (IOException e) { logger.log(Level.WARNING, "Splash screen failure", e); } } @@ -1689,7 +1694,7 @@ private static void startServer() { if (!freeColServer.registerWithMetaServer()) { fatal(Messages.message("server.noRouteToServer")); } - } catch (Exception e) { + } catch (FreeColException | IOException | XMLStreamException e) { logger.log(Level.SEVERE, "Load fail", e); fatal(Messages.message(badFile("error.couldNotLoad", saveGame)) + ": " + e); @@ -1705,13 +1710,13 @@ private static void startServer() { if (!freeColServer.registerWithMetaServer()) { fatal(Messages.message("server.noRouteToServer")); } - } catch (Exception e) { + } catch (IOException e) { fatal(Messages.message("server.initialize") + ": " + e.getMessage()); return; } if (publicServer && !freeColServer.getPublicServer()) { - gripe(Messages.message("server.noRouteToServer")); + gripe(StringTemplate.template("server.noRouteToServer")); } } diff --git a/src/net/sf/freecol/client/ClientOptions.java b/src/net/sf/freecol/client/ClientOptions.java index 20b76bb9db..de88fef503 100644 --- a/src/net/sf/freecol/client/ClientOptions.java +++ b/src/net/sf/freecol/client/ClientOptions.java @@ -619,17 +619,17 @@ public ClientOptions() { */ private boolean load(FreeColSavegameFile save) { if (save == null) return false; - boolean ret = false; + boolean ret; try ( FreeColXMLReader xr = save.getClientOptionsFreeColXMLReader(); ) { ret = load(xr); } catch (IOException|XMLStreamException ex) { - logger.log(Level.WARNING, "Load OptionGroup(" + getId() + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Load OptionGroup(" + getId() + ") from file " + save.getPath() + " crashed", ex); return false; } - logger.info("Load OptionGroup(" + getId() + ") from " + save.getPath() + if (logger.isLoggable(Level.INFO)) logger.info("Load OptionGroup(" + getId() + ") from " + save.getPath() + ((ret) ? " succeeded" : " failed")); return ret; } @@ -797,7 +797,7 @@ public void fixClientOptions() { ro.addItemValue(6, "6"); ro.setValue(value); // Make sure the value is valid } - } catch (Exception e) { + } catch (IllegalArgumentException | ClassCastException e) { logger.log(Level.WARNING, "Failed to fix " + DEFAULT_ZOOM_LEVEL + " option", e); } @@ -997,8 +997,8 @@ public Point getPanelPosition(String className) { return (etc == null) ? null : new Point(etc.getInteger(className + ".x"), etc.getInteger(className + ".y")); - } catch (Exception ex) { - logger.finest("Missing position option for " + className); + } catch (IllegalArgumentException ex) { + if (logger.isLoggable(Level.FINEST)) logger.finest("Missing position option for " + className); return null; } } @@ -1016,8 +1016,8 @@ public Dimension getPanelSize(String className) { return (etc == null) ? null : new Dimension(etc.getInteger(className + ".w"), etc.getInteger(className + ".h")); - } catch (Exception ex) { - logger.finest("Missing size option for " + className); + } catch (IllegalArgumentException ex) { + if (logger.isLoggable(Level.FINEST)) logger.finest("Missing size option for " + className); return null; } } diff --git a/src/net/sf/freecol/client/FreeColClient.java b/src/net/sf/freecol/client/FreeColClient.java index fb73c0f08a..aeb132ea69 100644 --- a/src/net/sf/freecol/client/FreeColClient.java +++ b/src/net/sf/freecol/client/FreeColClient.java @@ -49,6 +49,7 @@ import net.sf.freecol.common.io.FreeColDataFile; import net.sf.freecol.common.io.FreeColDirectories; import net.sf.freecol.common.io.FreeColSavegameFile; +import net.sf.freecol.common.FreeColException; import net.sf.freecol.common.io.FreeColTcFile; import net.sf.freecol.common.model.Game; import net.sf.freecol.common.model.Game.LogoutReason; @@ -246,7 +247,7 @@ public void run() { if (!FreeCol.getHeadless()) { try { gui.installLookAndFeel(fontName); - } catch (Exception e) { + } catch (FreeColException e) { FreeCol.fatal(logger, Messages.message("client.laf") + "\n" + e.getMessage()); } @@ -375,18 +376,18 @@ private ClientOptions loadClientOptions(File savedGameFile) { try { FreeColSavegameFile fcsf = new FreeColSavegameFile(savedGameFile); - logger.info("Merge client options from saved game: " + if (logger.isLoggable(Level.INFO)) logger.info("Merge client options from saved game: " + savedGameFile.getPath()); clop.merge(fcsf); } catch (IOException ioe) { - logger.log(Level.WARNING, "Could not open saved game " + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Could not open saved game " + savedGameFile.getPath(), ioe); } } final File userOptions = FreeColDirectories.getClientOptionsFile(); if (userOptions != null && userOptions.exists()) { - logger.info("Merge client options from user options file: " + if (logger.isLoggable(Level.INFO)) logger.info("Merge client options from user options file: " + userOptions.getPath()); clop.load(userOptions); } @@ -900,7 +901,7 @@ public FreeColServer startServer(boolean publicServer, } } catch (XMLStreamException xse) { return failToMain(xse, FreeCol.badFile("error.couldNotLoad", saveFile)); - } catch (Exception ex) { + } catch (FreeColException | IOException ex) { return failToMain(ex, "server.initialize"); } @@ -1023,7 +1024,7 @@ public void quit() { // Exit try { gui.quitGUI(); - } catch (Exception e) { + } catch (IllegalStateException e) { FreeCol.fatal(logger, "Failed to shutdown gui: " + e); } FreeCol.quit(0); @@ -1040,16 +1041,18 @@ private void overrideDefaultUncaughtExceptionHandler() { final boolean seriousError = (e instanceof Error); try { - logger.log(Level.WARNING, "Uncaught exception from thread: " + thread, e); + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Uncaught exception from thread: " + thread, e); if (seriousError) { gui.showErrorPanel(Messages.message("error.seriousError"), () -> { System.exit(1); }); } - } catch (Throwable t) { + } catch (IllegalStateException | SecurityException t) { if (seriousError) { - t.printStackTrace(); + if (logger.isLoggable(Level.SEVERE)) { + logger.log(Level.SEVERE, "Fatal error while showing error panel", t); + } System.exit(1); } } diff --git a/src/net/sf/freecol/client/control/ConnectController.java b/src/net/sf/freecol/client/control/ConnectController.java index 6fba891ff1..7f08f98a17 100644 --- a/src/net/sf/freecol/client/control/ConnectController.java +++ b/src/net/sf/freecol/client/control/ConnectController.java @@ -32,6 +32,7 @@ import java.util.logging.Logger; import javax.swing.SwingUtilities; +import javax.xml.stream.XMLStreamException; import net.sf.freecol.FreeCol; import net.sf.freecol.client.ClientOptions; @@ -94,15 +95,15 @@ private StringTemplate connect(String user, String host, int port) { if (askServer().connect(FreeCol.CLIENT_THREAD + user, host, port) != null) { getFreeColClient().changeClientState(false); - logger.info("Connected to " + host + ":" + port + if (logger.isLoggable(Level.INFO)) logger.info("Connected to " + host + ":" + port + " as " + user); } else { - logger.warning("Failed to connect to " + if (logger.isLoggable(Level.WARNING)) logger.warning("Failed to connect to " + host + ":" + port + " as " + user); err = StringTemplate.template("server.couldNotConnect"); } - } catch (Exception ex) { - logger.log(Level.SEVERE, "Exception when connecting to " + } catch (IOException ex) { + if (logger.isLoggable(Level.SEVERE)) logger.log(Level.SEVERE, "Exception when connecting to " + host + ":" + port + " as " + user, ex); err = FreeCol.errorFromException(ex, "server.couldNotConnect"); } @@ -132,7 +133,7 @@ public boolean requestLogout(LogoutReason reason) { } } - logger.info("Logout begin for client " + player.getName() + if (logger.isLoggable(Level.INFO)) logger.info("Logout begin for client " + player.getName() + ": " + reason); return askServer().logout(player, reason); } @@ -146,7 +147,7 @@ public boolean requestLogout(LogoutReason reason) { public boolean logout(LogoutReason reason) { final FreeColClient fcc = getFreeColClient(); final Player player = fcc.getMyPlayer(); - logger.info("Logout end for client " + player.getName() + if (logger.isLoggable(Level.INFO)) logger.info("Logout end for client " + player.getName() + ": " + reason); askServer().disconnect(); @@ -190,13 +191,13 @@ && askServer().login(name, player.getNationId(), FreeCol.getVersion(), fcc.getSinglePlayer(), fcc.currentPlayerIsMyPlayer())) { - logger.info("Reconnected for client " + name); + if (logger.isLoggable(Level.INFO)) logger.info("Reconnected for client " + name); } else { - logger.severe("Reconnect failed for client " + name); + if (logger.isLoggable(Level.SEVERE)) logger.severe("Reconnect failed for client " + name); fcc.askToQuit(); } } catch (IOException ioe) { - logger.log(Level.SEVERE, "Reconnect exception for client " + if (logger.isLoggable(Level.SEVERE)) logger.log(Level.SEVERE, "Reconnect exception for client " + name, ioe); fcc.quit(); } @@ -232,7 +233,7 @@ public boolean requestLogin(String user, String nationId, String host, int port) // Ask the server to log in a player with the given user // name. Control effectively transfers through the server // back to PGIH.login() and then to login() below. - logger.info("Login request for client " + FreeCol.getName()); + if (logger.isLoggable(Level.INFO)) logger.info("Login request for client " + FreeCol.getName()); if (askServer().login(user, nationId, FreeCol.getVersion(), fcc.getSinglePlayer(), fcc.currentPlayerIsMyPlayer())) { @@ -281,14 +282,14 @@ public void login(ServerState state, Game game, String user, StringTemplate err = StringTemplate.template("server.noSuchPlayer") .addName("%player%", user); getGUI().showErrorPanel(err); - logger.warning(Messages.message(err)); + if (logger.isLoggable(Level.WARNING)) logger.warning(Messages.message(err)); return; } // Reattach to the game fcc.login(state == ServerState.IN_GAME, game, player, single); if (current) game.setCurrentPlayer(player); - logger.info("Login accepted for client " + player.getName() + if (logger.isLoggable(Level.INFO)) logger.info("Login accepted for client " + player.getName() + " to " + ((fcc.isInGame()) ? "running" : (game.allPlayersReadyToLaunch()) ? "ready" : "new") + " " + ((single) ? "single" : "multi") @@ -369,17 +370,17 @@ public boolean startSavedGame(File file) { final ClientOptions options = getClientOptions(); final boolean defaultSinglePlayer; final boolean defaultPublicServer; - FreeColSavegameFile fis = null; + FreeColSavegameFile fis; try { fis = new FreeColSavegameFile(file); } catch (FileNotFoundException fnfe) { - logger.log(Level.WARNING, "Can not find file: " + file.getName(), + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Can not find file: " + file.getName(), fnfe); gui.showErrorPanel(fnfe, FreeCol.badFile("error.couldNotFind", file)); return false; } catch (IOException ioe) { - logger.log(Level.WARNING, "Could not load file: " + file.getName(), + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Could not load file: " + file.getName(), ioe); gui.showErrorPanel(ioe, FreeCol.badFile("error.couldNotLoad", file)); @@ -388,11 +389,11 @@ public boolean startSavedGame(File file) { options.merge(fis); options.fixClientOptions(); - List values = null; + List values; try { values = fis.peekAttributes(savedKeys); - } catch (Exception ex) { - logger.log(Level.WARNING, "Could not read from: " + file.getName(), + } catch (IOException | XMLStreamException ex) { + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Could not read from: " + file.getName(), ex); gui.showErrorPanel(ex, FreeCol.badFile("error.couldNotLoad", file)); diff --git a/src/net/sf/freecol/client/control/InGameController.java b/src/net/sf/freecol/client/control/InGameController.java index 07cb42e52e..bfec56b434 100644 --- a/src/net/sf/freecol/client/control/InGameController.java +++ b/src/net/sf/freecol/client/control/InGameController.java @@ -243,7 +243,7 @@ private Settlement getSettlementAt(Tile tile, Direction direction) { */ private StringTemplate getNationAt(Tile tile, Direction direction) { Tile newTile = tile.getNeighbourOrNull(direction); - Player player = null; + Player player; if (newTile.hasSettlement()) { player = newTile.getSettlement().getOwner(); } else if (newTile.getFirstUnit() != null) { @@ -626,27 +626,28 @@ private boolean askAssignTradeRoute(Unit unit, TradeRoute tradeRoute) { */ private boolean askClaimTile(Player player, Tile tile, FreeColGameObject claimant, int price) { + int claimPrice = price; final Player owner = tile.getOwner(); - if (price < 0) { // not for sale + if (claimPrice < 0) { // not for sale return false; - } else if (price > 0) { // for sale + } else if (claimPrice > 0) { // for sale ClaimAction act - = getGUI().getClaimChoice(tile, player, price, owner); + = getGUI().getClaimChoice(tile, player, claimPrice, owner); if (act == null) return false; // Cancelled switch (act) { case CLAIM_ACCEPT: // accepted price break; case CLAIM_STEAL: - price = STEAL_LAND; + claimPrice = STEAL_LAND; break; default: - logger.warning("Claim dialog fail: " + act); + if (logger.isLoggable(Level.WARNING)) logger.warning("Claim dialog fail: " + act); return false; } - } // else price == 0 and we can just proceed to claim + } // else claimPrice == 0 and we can just proceed to claim // Ask the server - return askServer().claimTile(tile, claimant, price) + return askServer().claimTile(tile, claimant, claimPrice) && player.owns(tile); } @@ -678,13 +679,11 @@ private boolean askEmbark(Unit unit, Unit carrier) { EuropeWas europeWas = (unit.isInEurope()) ? new EuropeWas(unit.getOwner().getEurope()) : null; UnitWas unitWas = new UnitWas(unit); - if (askServer().embark(unit, carrier, null) - && unit.getLocation() == carrier) { - sound("sound.event.loadCargo"); - fireChanges(unitWas, colonyWas, europeWas); - return true; - } - return false; + if (!askServer().embark(unit, carrier, null) + || unit.getLocation() != carrier) return false; + sound("sound.event.loadCargo"); + fireChanges(unitWas, colonyWas, europeWas); + return true; } /** @@ -728,9 +727,9 @@ private void emigration(Player player, int n, boolean fountainOfYouth) { final Europe europe = player.getEurope(); if (europe == null) return; - for (; n > 0 || player.checkEmigrate() ; n--) { + for (int remaining = n; remaining > 0 || player.checkEmigrate(); remaining--) { if (!allSame(europe.getExpandedRecruitables(false))) { - showEmigrationDialog(player, fountainOfYouth, n); + showEmigrationDialog(player, fountainOfYouth, remaining); return; } Unit u = askEmigrate(europe, Europe.MigrationType.getDefaultSlot()); @@ -755,7 +754,8 @@ private boolean askLoadGoods(Location loc, GoodsType type, int amount, // Size check, if there are spare holds they can be filled, but... int loadable = carrier.getLoadableAmount(type); - if (amount > loadable) amount = loadable; + int loadAmount = amount; + if (loadAmount > loadable) loadAmount = loadable; final Player player = carrier.getOwner(); @@ -764,7 +764,7 @@ private boolean askLoadGoods(Location loc, GoodsType type, int amount, if (!player.canTrade(type)) return false; // Check that the purchase is funded. - if (!player.checkGold(player.getMarket().getBidPrice(type, amount))) { + if (!player.checkGold(player.getMarket().getBidPrice(type, loadAmount))) { showInformationPanel(null, "info.notEnoughGold"); return false; } @@ -772,7 +772,7 @@ private boolean askLoadGoods(Location loc, GoodsType type, int amount, // Try to purchase. int oldAmount = carrier.getGoodsContainer().getGoodsCount(type); - if (askServer().loadGoods(loc, type, amount, carrier) + if (askServer().loadGoods(loc, type, loadAmount, carrier) && carrier.getGoodsContainer().getGoodsCount(type) != oldAmount) { return true; } @@ -858,15 +858,19 @@ private void autoSaveGame () { // if "last-turn" file exists, shift it to "before-last-turn" file if (lastTurnFile != null) { if (lastTurnFile.exists()) { - if (beforeLastTurnFile.exists()) deleteFile(beforeLastTurnFile); - try { - if (!lastTurnFile.renameTo(beforeLastTurnFile)) { - logger.warning("Could not rename: " - + lastTurnFile.getPath()); + if (beforeLastTurnFile == null) { + logger.warning("No autosave target for before-last-turn."); + } else { + if (beforeLastTurnFile.exists()) deleteFile(beforeLastTurnFile); + try { + if (!lastTurnFile.renameTo(beforeLastTurnFile)) { + if (logger.isLoggable(Level.WARNING)) logger.warning("Could not rename: " + + lastTurnFile.getPath()); + } + } catch (SecurityException ex) { + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Could not rename: " + + lastTurnFile.getPath(), ex); } - } catch (NullPointerException|SecurityException ex) { - logger.log(Level.WARNING, "Could not rename: " - + lastTurnFile.getPath(), ex); } } saveGame(lastTurnFile); @@ -887,6 +891,7 @@ private void autoSaveGame () { * @param file The {@code File}. * @return True if the game was saved. */ + @SuppressWarnings("PMD.GuardLogStatement") private boolean saveGame(final File file) { if (file == null) return false; final FreeColServer server = getFreeColServer(); @@ -898,7 +903,7 @@ private boolean saveGame(final File file) { result = true; } catch (IOException ioe) { error(FreeCol.badFile("error.couldNotSave", file), null); - logger.log(Level.WARNING, "Save fail", ioe); + logger.log(Level.WARNING, ioe, () -> "Save fail"); } finally { showStatusPanel(null); } @@ -917,7 +922,7 @@ private boolean saveGame(final File file) { */ private void startIgnoringMessage(String key, Turn turn) { messagesToIgnore.put(key, turn.getNumber()); - logger.finer("Ignore message start: " + key); + if (logger.isLoggable(Level.FINER)) logger.finer("Ignore message start: " + key); } /** @@ -927,7 +932,7 @@ private void startIgnoringMessage(String key, Turn turn) { */ private void stopIgnoringMessage(String key) { messagesToIgnore.remove(key); - logger.finer("Ignore message stop: " + key); + if (logger.isLoggable(Level.FINER)) logger.finer("Ignore message stop: " + key); } /** @@ -948,10 +953,8 @@ private void reapIgnoredMessages(Turn turn) { * @return True if the message should continue to be ignored. */ private boolean continueIgnoreMessage(String key, Turn turn) { - Integer value = -1; - boolean ret = key != null - && (value = messagesToIgnore.get(key)) != null - && value + 1 == turn.getNumber(); + Integer value = (key == null) ? null : messagesToIgnore.get(key); + boolean ret = value != null && value + 1 == turn.getNumber(); if (ret) messagesToIgnore.put(key, value + 1); return ret; } @@ -986,8 +989,8 @@ private boolean displayModelMessages(final boolean allMessages, && !continueIgnoreMessage(m.getIgnoredMessageKey(), thisTurn)) { messages.add(m); } - } catch (RuntimeException rte) { - logger.warning("Bogus ModelMessage with key<" + key + } catch (IllegalArgumentException iae) { + if (logger.isLoggable(Level.WARNING)) logger.warning("Bogus ModelMessage with key<" + key + ">: " + m); } m.setDisplayed(true); @@ -1173,53 +1176,56 @@ private boolean moveToDestination(Unit unit, List messages) { ret = true; // also invalid, but trade route check needed first } else if (!changeState(unit, UnitState.ACTIVE)) { ret = true; // another error case - } else if ((path = unit.findPath(destination)) == null) { - // No path to destination. Give the player a chance to do - // something about it, but default to skipping this unit as - // the path blockage is most likely just transient - StringTemplate src = unit.getLocation() - .getLocationLabelFor(player); - StringTemplate dst = destination.getLocationLabelFor(player); - StringTemplate template = StringTemplate - .template("info.moveToDestinationFailed") - .addStringTemplate("%unit%", - unit.getLabel(Unit.UnitLabelType.NATIONAL)) - .addStringTemplate("%location%", src) - .addStringTemplate("%destination%", dst); - showInformationPanel(unit, template); - changeState(unit, UnitState.SKIPPED); - ret = false; - } else if (!movePath(unit, path)) { - ret = false; // ask the player to resolve the movePath problem - } else if (unit.isDisposed() || !player.owns(unit)) { - /* - * Disposed in combat or cashed in treasure train. Do NOT display - * to the player (or we get an error message). - */ - return true; - } else if (unit.isAtLocation(destination)) { - final Colony colony = (unit.hasTile()) ? unit.getTile().getColony() - : null; - // Clear ordinary destinations if arrived. - if (!askClearGotoOrders(unit)) { - ret = false; // Should not happen. Desync? Ask the user. - } else if (colony != null) { - // Always ask to be selected if arriving at a colony - // unless the unit cashed in (and thus gone), and bring - // up the colony panel so something can be done with the - // unit - if (checkCashInTreasureTrain(unit)) { - ret = true; + } else { + path = unit.findPath(destination); + if (path == null) { + // No path to destination. Give the player a chance to do + // something about it, but default to skipping this unit as + // the path blockage is most likely just transient + StringTemplate src = unit.getLocation() + .getLocationLabelFor(player); + StringTemplate dst = destination.getLocationLabelFor(player); + StringTemplate template = StringTemplate + .template("info.moveToDestinationFailed") + .addStringTemplate("%unit%", + unit.getLabel(Unit.UnitLabelType.NATIONAL)) + .addStringTemplate("%location%", src) + .addStringTemplate("%destination%", dst); + showInformationPanel(unit, template); + changeState(unit, UnitState.SKIPPED); + ret = false; + } else if (!movePath(unit, path)) { + ret = false; // ask the player to resolve the movePath problem + } else if (unit.isDisposed() || !player.owns(unit)) { + /* + * Disposed in combat or cashed in treasure train. Do NOT display + * to the player (or we get an error message). + */ + return true; + } else if (unit.isAtLocation(destination)) { + final Colony colony = (unit.hasTile()) ? unit.getTile().getColony() + : null; + // Clear ordinary destinations if arrived. + if (!askClearGotoOrders(unit)) { + ret = false; // Should not happen. Desync? Ask the user. + } else if (colony != null) { + // Always ask to be selected if arriving at a colony + // unless the unit cashed in (and thus gone), and bring + // up the colony panel so something can be done with the + // unit + if (checkCashInTreasureTrain(unit)) { + ret = true; + } else { + showColonyPanelWithCarrier(colony, unit); + ret = false; + } } else { - showColonyPanelWithCarrier(colony, unit); - ret = false; + // If the unit has moves left, select it + ret = unit.getMovesLeft() == 0; } - } else { - // If the unit has moves left, select it - ret = unit.getMovesLeft() == 0; + } else { // Still in transit, do not select + ret = true; } - } else { // Still in transit, do not select - ret = true; } return ret; } @@ -1232,39 +1238,39 @@ private boolean moveToDestination(Unit unit, List messages) { * @return True if automatic movement of the unit can proceed. */ private boolean movePath(Unit unit, PathNode path) { - for (; path != null; path = path.next) { - if (unit.isAtLocation(path.getLocation())) continue; + for (PathNode node = path; node != null; node = node.next) { + if (unit.isAtLocation(node.getLocation())) continue; - if (path.getLocation() instanceof Europe) { + if (node.getLocation() instanceof Europe) { if (unit.hasTile() && unit.getTile().isDirectlyHighSeasConnected()) { - return moveTowardEurope(unit, (Europe)path.getLocation()); + return moveTowardEurope(unit, (Europe)node.getLocation()); } - logger.warning("Can not move to Europe from " + if (logger.isLoggable(Level.WARNING)) logger.warning("Can not move to Europe from " + unit.getLocation() - + " on path: " + path.fullPathToString()); + + " on path: " + node.fullPathToString()); return false; - } else if (path.getLocation() instanceof Tile) { - if (path.getDirection() == null) { + } else if (node.getLocation() instanceof Tile) { + if (node.getDirection() == null) { if (unit.isInEurope()) { return moveAwayFromEurope(unit, unit.getGame().getMap()); } - logger.warning("Null direction on path: " - + path.fullPathToString()); + if (logger.isLoggable(Level.WARNING)) logger.warning("Null direction on path: " + + node.fullPathToString()); return false; } - if (!moveDirection(unit, path.getDirection(), false)) { + if (!moveDirection(unit, node.getDirection(), false)) { // Lack of moves is an expected non-failure condition - return unit.getMoveType(path.getDirection()) + return unit.getMoveType(node.getDirection()) == Unit.MoveType.MOVE_NO_MOVES; } - } else if (path.getLocation() instanceof Unit) { - return moveEmbark(unit, path.getDirection()); + } else if (node.getLocation() instanceof Unit) { + return moveEmbark(unit, node.getDirection()); } else { - logger.warning("Bad path: " + path.fullPathToString()); + if (logger.isLoggable(Level.WARNING)) logger.warning("Bad path: " + node.fullPathToString()); return false; } } @@ -1617,7 +1623,7 @@ && getGUI().confirmPreCombat(unit, target)) { break; default: - logger.warning("showArmedUnitSettlementDialog fail: " + act); + if (logger.isLoggable(Level.WARNING)) logger.warning("showArmedUnitSettlementDialog fail: " + act); break; } return false; @@ -1739,7 +1745,7 @@ private boolean moveEmbark(Unit unit, Direction direction) { final Tile sourceTile = unit.getTile(); final Tile destinationTile = sourceTile.getNeighbourOrNull(direction); - Unit carrier = null; + Unit carrier; List> choices = transform(destinationTile.getUnits(), u -> u.canAdd(unit), @@ -1974,7 +1980,7 @@ private boolean moveScoutColony(Unit unit, Direction direction) { case SCOUT_COLONY_SPY: return moveSpy(unit, direction); default: - logger.warning("showScoutForeignColonyDialog fail: " + act); + if (logger.isLoggable(Level.WARNING)) logger.warning("showScoutForeignColonyDialog fail: " + act); break; } return true; @@ -2020,7 +2026,7 @@ private boolean moveScoutIndianSettlement(Unit unit, Direction direction) { case SCOUT_SETTLEMENT_TRIBUTE: return moveTribute(unit, 1, direction); default: - logger.warning("showScoutIndianSettlementDialog fail: " + act); + if (logger.isLoggable(Level.WARNING)) logger.warning("showScoutIndianSettlementDialog fail: " + act); break; } return false; @@ -2038,7 +2044,7 @@ private boolean moveSpy(Unit unit, Direction direction) { if (settlement instanceof Colony && !unit.getOwner().owns(settlement)) { askServer().spy(unit, settlement); } else { - logger.warning("Unit " + unit + " can not spy on " + settlement); + if (logger.isLoggable(Level.WARNING)) logger.warning("Unit " + unit + " can not spy on " + settlement); } return false; } @@ -2410,7 +2416,7 @@ private boolean loadUnitAtStop(Unit unit, LogBuilder lb) { // Do not load this goods type if (ag.getAmount() <= 0) iterator.remove(); - logger.log(Level.FINEST, "Load " + tradeRoute.getName() + if (logger.isLoggable(Level.FINEST)) logger.log(Level.FINEST, "Load " + tradeRoute.getName() + " with " + unit.getId() + " at " + stop.getLocation() + " of " + type.getSuffix() + " from " + present + " exporting " + exportAmount + " importing " + importAmount @@ -2523,7 +2529,7 @@ private boolean unloadUnitAtStop(Unit unit, LogBuilder lb) { if (goodsTypesToLoad.contains(type)) continue; // Keep this cargo. int present = goods.getAmount(); if (present <= 0) { - logger.warning("Unexpected empty goods unload " + goods); + if (logger.isLoggable(Level.WARNING)) logger.warning("Unexpected empty goods unload " + goods); continue; } int toUnload = present; @@ -2554,7 +2560,7 @@ private boolean unloadUnitAtStop(Unit unit, LogBuilder lb) { case ClientOptions.UNLOAD_OVERFLOW_RESPONSE_ALWAYS: break; default: - logger.warning("Illegal UNLOAD_OVERFLOW_RESPONSE: " + if (logger.isLoggable(Level.WARNING)) logger.warning("Illegal UNLOAD_OVERFLOW_RESPONSE: " + Integer.toString(option)); break; } @@ -3296,7 +3302,8 @@ public void diplomacyHandler(final FreeColGameObject our, final DiplomaticTrade agreement) { final Player player = getMyPlayer(); final Player otherPlayer = agreement.getOtherPlayer(player); - StringTemplate t, nation = otherPlayer.getNationLabel(); + StringTemplate t; + StringTemplate nation = otherPlayer.getNationLabel(); switch (agreement.getStatus()) { case ACCEPT_TRADE: @@ -3341,7 +3348,7 @@ public void diplomacyHandler(final FreeColGameObject our, }); break; default: - logger.warning("Bogus trade status: " + agreement.getStatus()); + if (logger.isLoggable(Level.WARNING)) logger.warning("Bogus trade status: " + agreement.getStatus()); break; } } @@ -3431,7 +3438,7 @@ public boolean equipUnitForRole(Unit unit, Role role, int roleCount) { ColonyWas colonyWas = null; EuropeWas europeWas = null; MarketWas marketWas = null; - int price = -1; + int price; List req = unit.getGoodsDifference(role, roleCount); if (unit.isInEurope()) { @@ -3538,7 +3545,7 @@ public void featureChangeHandler(FreeColGameObject parent, Player player = (Player)parent; player.addHistory((HistoryEvent)fco); } else { - logger.warning("Feature change NYI: " + if (logger.isLoggable(Level.WARNING)) logger.warning("Feature change NYI: " + parent + "/" + add + "/" + fco); } } else if (fco instanceof LastSale) { @@ -3546,7 +3553,7 @@ public void featureChangeHandler(FreeColGameObject parent, Player player = (Player)parent; player.addLastSale((LastSale)fco); } else { - logger.warning("Feature change NYI: " + if (logger.isLoggable(Level.WARNING)) logger.warning("Feature change NYI: " + parent + "/" + add + "/" + fco); } } else if (fco instanceof ModelMessage) { @@ -3554,11 +3561,11 @@ public void featureChangeHandler(FreeColGameObject parent, Player player = (Player)parent; player.addModelMessage((ModelMessage)fco); } else { - logger.warning("Feature change NYI: " + if (logger.isLoggable(Level.WARNING)) logger.warning("Feature change NYI: " + parent + "/" + add + "/" + fco); } } else { - logger.warning("featureChange unrecognized: " + fco); + if (logger.isLoggable(Level.WARNING)) logger.warning("featureChange unrecognized: " + fco); } } } @@ -3786,9 +3793,8 @@ private boolean joinColony(Unit unit) { * @return True if the unit left the ship. */ public boolean leaveShip(Unit unit) { - Unit carrier; - if (unit == null || (carrier = unit.getCarrier()) == null - || !requireOurTurn()) return false; + Unit carrier = (unit == null) ? null : unit.getCarrier(); + if (unit == null || carrier == null || !requireOurTurn()) return false; // Proceed to disembark UnitWas unitWas = new UnitWas(unit); @@ -4096,7 +4102,7 @@ public NationSummary nationSummary(Player player) { public void nationSummaryHandler(Player other, NationSummary ns) { final Player player = getMyPlayer(); player.putNationSummary(other, ns); - logger.info("Updated nation summary of " + other.getSuffix() + if (logger.isLoggable(Level.INFO)) logger.info("Updated nation summary of " + other.getSuffix() + " for " + player.getSuffix() + " with " + ns); } @@ -4114,7 +4120,7 @@ public void nativeTradeHandler(NativeTradeAction action, NativeTrade nt) { final Unit unit = nt.getUnit(); final Player player = getMyPlayer(); if (!player.owns(unit)) { - logger.warning("We do not own the trading unit: " + unit); + if (logger.isLoggable(Level.WARNING)) logger.warning("We do not own the trading unit: " + unit); return; } @@ -4185,7 +4191,7 @@ public void nativeTradeHandler(NativeTradeAction action, NativeTrade nt) { return; case NAK_INVALID: // Should not happen, log and fail quietly. default: - logger.warning("Bogus native trade: " + nt); + if (logger.isLoggable(Level.WARNING)) logger.warning("Bogus native trade: " + nt); return; } @@ -4209,6 +4215,9 @@ public void nativeTradeHandler(NativeTradeAction action, NativeTrade nt) { */ private void nativeTrade(NativeTrade nt, TradeAction act, NativeTradeItem nti, StringTemplate prompt) { + TradeAction currentAct = act; + NativeTradeItem currentItem = nti; + StringTemplate currentPrompt = prompt; final IndianSettlement is = nt.getIndianSettlement(); final Unit unit = nt.getUnit(); final StringTemplate base = StringTemplate @@ -4227,79 +4236,79 @@ private void nativeTrade(NativeTrade nt, TradeAction act, return new ChoiceItem<>(label, i); }; while (!nt.getDone()) { - if (act == null) { - if (prompt == null) prompt = base; - act = getGUI().getIndianSettlementTradeChoice(is, prompt, + if (currentAct == null) { + if (currentPrompt == null) currentPrompt = base; + currentAct = getGUI().getIndianSettlementTradeChoice(is, currentPrompt, nt.canBuy(), nt.canSell(), nt.canGift()); - if (act == null) break; - prompt = base; // Revert to base after first time through + if (currentAct == null) break; + currentPrompt = base; // Revert to base after first time through } - switch (act) { + switch (currentAct) { case BUY: - act = null; - if (nti == null) { - nti = getGUI().modalChoiceDialog(unit.getTile(), + currentAct = null; + if (currentItem == null) { + currentItem = getGUI().modalChoiceDialog(unit.getTile(), StringTemplate.key("buyProposition.text"), is, "nothing", transform(nt.getSettlementToUnit(), NativeTradeItem::priceIsValid, goodsMapper)); - if (nti == null) break; - nt.setItem(nti); + if (currentItem == null) break; + nt.setItem(currentItem); } TradeBuyAction tba = getGUI().getBuyChoice(unit, is, - nti.getGoods(), nti.getPrice(), - unit.getOwner().checkGold(nti.getPrice())); + currentItem.getGoods(), currentItem.getPrice(), + unit.getOwner().checkGold(currentItem.getPrice())); if (tba == TradeBuyAction.BUY) { askServer().nativeTrade(NativeTradeAction.BUY, nt); return; } else if (tba == TradeBuyAction.HAGGLE) { - nti.setPrice(NativeTradeItem.PRICE_UNSET); + currentItem.setPrice(NativeTradeItem.PRICE_UNSET); askServer().nativeTrade(NativeTradeAction.BUY, nt); return; } break; case SELL: - act = null; - if (nti == null) { - nti = getGUI().modalChoiceDialog(unit.getTile(), + currentAct = null; + if (currentItem == null) { + currentItem = getGUI().modalChoiceDialog(unit.getTile(), StringTemplate.key("sellProposition.text"), is, "nothing", transform(nt.getUnitToSettlement(), NativeTradeItem::priceIsValid, goodsMapper)); - if (nti == null) break; - nt.setItem(nti); + if (currentItem == null) break; + nt.setItem(currentItem); } TradeSellAction tsa = getGUI().getSellChoice(unit, is, - nti.getGoods(), nti.getPrice()); + currentItem.getGoods(), currentItem.getPrice()); if (tsa == TradeSellAction.SELL) { askServer().nativeTrade(NativeTradeAction.SELL, nt); return; } else if (tsa == TradeSellAction.HAGGLE) { - nti.setPrice(NativeTradeItem.PRICE_UNSET); + currentItem.setPrice(NativeTradeItem.PRICE_UNSET); askServer().nativeTrade(NativeTradeAction.SELL, nt); return; } break; case GIFT: - act = null; - nti = getGUI().modalChoiceDialog(unit.getTile(), + currentAct = null; + currentItem = getGUI().modalChoiceDialog(unit.getTile(), StringTemplate.key("gift.text"), is, "cancel", transform(nt.getUnitToSettlement(), alwaysTrue(), goodsMapper)); - if (nti != null) { - nt.setItem(nti); + if (currentItem != null) { + nt.setItem(currentItem); askServer().nativeTrade(NativeTradeAction.GIFT, nt); return; } break; default: - logger.warning("showIndianSettlementTradeDialog fail: " - + act); + if (logger.isLoggable(Level.WARNING)) logger.warning("showIndianSettlementTradeDialog fail: " + + currentAct); nt.setDone(); break; } - nti = null; + currentItem = null; } askServer().nativeTrade(NativeTradeAction.CLOSE, nt); getGUI().updateMapControls(); @@ -4446,12 +4455,12 @@ private boolean newTurn(int turn) { final Player player = getMyPlayer(); if (turn < 0) { - logger.warning("Bad turn in newTurn: " + turn); + if (logger.isLoggable(Level.WARNING)) logger.warning("Bad turn in newTurn: " + turn); return false; } Turn newTurn = new Turn(turn); game.setTurn(newTurn); - logger.info("New turn: " + newTurn + "/" + turn); + if (logger.isLoggable(Level.INFO)) logger.info("New turn: " + newTurn + "/" + turn); if (getClientOptions().getBoolean(ClientOptions.AUDIO_ALERTS)) { sound("sound.event.alertSound"); @@ -4505,7 +4514,7 @@ public void partialHandler(FreeColGameObject fcgo, Introspector intro = new Introspector(fcgo.getClass(), e.getKey()); intro.setter(fcgo, e.getValue()); // Possible -vis(player) } catch (Introspector.IntrospectorException ie) { - logger.log(Level.WARNING, "Partial update setter fail: " + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Partial update setter fail: " + fcgo.getId() + "/" + e.getKey() + "=" + e.getValue(), ie); } } @@ -4681,7 +4690,8 @@ public boolean recruitUnitInEurope(int index) { public void removeHandler(List objects, FreeColGameObject divert) { final Player player = getMyPlayer(); - boolean visibilityChange = false, updateUnit = false; + boolean visibilityChange = false; + boolean updateUnit = false; for (FreeColGameObject fcgo : objects) { if (divert != null) player.divertModelMessages(fcgo, divert); @@ -4726,7 +4736,7 @@ public boolean rename(Nameable object) { if (!(object instanceof Ownable) || !player.owns((Ownable)object)) return false; - String name = null; + String name; if (object instanceof Colony) { Colony colony = (Colony) object; name = getGUI().modalInputDialog(colony.getTile(), @@ -4753,7 +4763,7 @@ public boolean rename(Nameable object) { unit.getName(), "rename", "cancel"); if (name == null) return false; // User cancelled } else { - logger.warning("Tried to rename an unsupported Nameable: " + if (logger.isLoggable(Level.WARNING)) logger.warning("Tried to rename an unsupported Nameable: " + object); return false; } @@ -5164,8 +5174,11 @@ public boolean trainUnitInEurope(UnitType unitType) { EuropeWas europeWas = new EuropeWas(europe); Unit newUnit = null; - boolean ret = askServer().trainUnitInEurope(unitType) - && (newUnit = europeWas.getNewUnit()) != null; + boolean ret = askServer().trainUnitInEurope(unitType); + if (ret) { + newUnit = europeWas.getNewUnit(); + ret = newUnit != null; + } if (ret) { fireChanges(europeWas); changeView(newUnit, false); @@ -5266,11 +5279,11 @@ public void updateHandler(List objects) { for (FreeColObject fco : objects) { FreeColGameObject fcgo = game.getFreeColGameObject(fco.getId()); if (fcgo == null) { - logger.warning("Update of missing FCGO: " + fco.getId()); + if (logger.isLoggable(Level.WARNING)) logger.warning("Update of missing FCGO: " + fco.getId()); continue; } if (!fcgo.copyIn(fco)) { // Possibly -vis(player) - logger.warning("Update copy-in failed: " + fco.getId()); + if (logger.isLoggable(Level.WARNING)) logger.warning("Update copy-in failed: " + fco.getId()); continue; } else if (fco instanceof Tile) { invokeLater(() -> getGUI().refreshTile((Tile)fco)); diff --git a/src/net/sf/freecol/client/control/PreGameController.java b/src/net/sf/freecol/client/control/PreGameController.java index 80bde2042b..73ce851016 100644 --- a/src/net/sf/freecol/client/control/PreGameController.java +++ b/src/net/sf/freecol/client/control/PreGameController.java @@ -46,6 +46,7 @@ import net.sf.freecol.common.resources.AudioResource; import net.sf.freecol.common.resources.ResourceManager; import net.sf.freecol.common.util.Utils; +import java.util.logging.Level; /** @@ -340,10 +341,10 @@ public void updateHandler(List objects) { final FreeColClient fcc = getFreeColClient(); fcc.addSpecificationActions(((Game)fco).getSpecification()); } else { - logger.warning("Pre-game copy-in failed: " + fco.getId()); + if (logger.isLoggable(Level.WARNING)) logger.warning("Pre-game copy-in failed: " + fco.getId()); } } else { - logger.warning("Game node expected: " + fco.getId()); + if (logger.isLoggable(Level.WARNING)) logger.warning("Game node expected: " + fco.getId()); } } } diff --git a/src/net/sf/freecol/client/control/SoundController.java b/src/net/sf/freecol/client/control/SoundController.java index dec05b6d86..a787e2c3bd 100644 --- a/src/net/sf/freecol/client/control/SoundController.java +++ b/src/net/sf/freecol/client/control/SoundController.java @@ -32,6 +32,7 @@ import net.sf.freecol.common.option.PercentageOption; import net.sf.freecol.common.resources.ResourceManager; import net.sf.freecol.common.sound.SoundPlayer; +import java.util.logging.Level; /** * Controls the SoundPlayer. @@ -61,8 +62,8 @@ public SoundController(FreeColClient freeColClient, boolean sound) { try { amo = opts.getOption(ClientOptions.AUDIO_MIXER, AudioMixerOption.class); - } catch (Exception ex) { - logger.warning(ex.getMessage()); + } catch (IllegalArgumentException ex) { + if (logger.isLoggable(Level.WARNING)) logger.warning(ex.getMessage()); } if (amo == null) { @@ -72,7 +73,7 @@ public SoundController(FreeColClient freeColClient, boolean sound) { // created, but if it has a bad mixer sound output will be // suspended. The hope is that the user will change the // mixer option to one that works. - logger.info("Create sound player with " + amo); + if (logger.isLoggable(Level.INFO)) logger.info("Create sound player with " + amo); this.soundPlayer = new SoundPlayer(amo, opts.getOption(ClientOptions.SOUND_EFFECTS_VOLUME, PercentageOption.class)); this.musicPlayer = new SoundPlayer(amo, opts.getOption(ClientOptions.MUSIC_VOLUME, PercentageOption.class)); } @@ -122,7 +123,7 @@ private void play(SoundPlayer sp, String sound) { File file = ResourceManager.getAudio(sound); if (file == null) return; boolean playing = sp.playOnce(file); - logger.finest(((playing) ? "Queued" : "Fail on") + if (logger.isLoggable(Level.FINEST)) logger.finest(((playing) ? "Queued" : "Fail on") + " sound: " + sound); } diff --git a/src/net/sf/freecol/client/control/package-info.java b/src/net/sf/freecol/client/control/package-info.java index f7d6cc10a7..aa6e8a71fa 100644 --- a/src/net/sf/freecol/client/control/package-info.java +++ b/src/net/sf/freecol/client/control/package-info.java @@ -1,5 +1,5 @@ /** - *

FreeCol Client Control package

+ *

FreeCol Client Control package

* *

Contains the classes responsible for the control of the game.

* diff --git a/src/net/sf/freecol/client/gui/Canvas.java b/src/net/sf/freecol/client/gui/Canvas.java index a956cab463..6d0a96dd1b 100644 --- a/src/net/sf/freecol/client/gui/Canvas.java +++ b/src/net/sf/freecol/client/gui/Canvas.java @@ -256,7 +256,7 @@ public void componentHidden(ComponentEvent e) { updateRepaintTimer(false); this.animationTimer.start(); - logger.info("Canvas created with bounds: " + windowBounds); + if (logger.isLoggable(Level.INFO)) logger.info("Canvas created with bounds: " + windowBounds); } @@ -285,7 +285,7 @@ private void updateSize() { Dimension size = getSize(); if (oldSize.width != size.width || oldSize.height != size.height) { - logger.info("Canvas resize from " + oldSize + " to " + size); + if (logger.isLoggable(Level.INFO)) logger.info("Canvas resize from " + oldSize + " to " + size); oldSize = size; canvasMapViewer.changeSize(size); if (removeMapControls()) { @@ -353,7 +353,7 @@ private void updateFrameSizesAndPositions(Dimension canvasSize) { final Point loc = f.getLocation(); final int newX = (loc.x + newSize.width > canvasSize.width) ? canvasSize.width - newSize.width : loc.x; final int newY = (loc.y + newSize.height > canvasSize.height) ? canvasSize.height - newSize.height : loc.y; - f.setLocation(new Point(Math.max(0, newX), Math.max(0, newY))); + f.setLocation(Math.max(0, newX), Math.max(0, newY)); /* * Maintains logical positions (like centered) after resize. @@ -442,7 +442,7 @@ private static boolean checkWindowed(GraphicsDevice gd, ret = false; } else { logger.warning("Full screen mode not supported."); - System.err.println(Messages.message("client.fullScreen")); + if (logger.isLoggable(Level.WARNING)) logger.warning(Messages.message("client.fullScreen")); ret = true; } } else { @@ -466,6 +466,8 @@ private static boolean checkWindowed(GraphicsDevice gd, private JInternalFrame addAsFrame(JComponent comp, boolean toolBox, PopupPosition popupPosition, boolean resizable) { + PopupPosition framePosition = popupPosition; + boolean frameResizable = resizable; @SuppressWarnings("serial") final JInternalFrame f = (toolBox) ? new ToolBoxFrame() : new JInternalFrame() { @Override @@ -481,15 +483,15 @@ public Dimension getMinimumSize() { if (comp instanceof FreeColPanel) { final FreeColPanel freeColPanel = (FreeColPanel) comp; fullscreenPanel = freeColPanel.isFullscreen(); - if (popupPosition == null) { - popupPosition = freeColPanel.getFramePopupPosition(); + if (framePosition == null) { + framePosition = freeColPanel.getFramePopupPosition(); } } else { fullscreenPanel = false; } if (fullscreenPanel) { - resizable = false; + frameResizable = false; } Container con = f.getContentPane(); @@ -556,13 +558,13 @@ public Dimension getMinimumSize() { if (fullscreenPanel) { f.setLocation(0, 0); } else { - final Point p = chooseLocation(comp, size.width, size.height, popupPosition); + final Point p = chooseLocation(comp, size.width, size.height, framePosition); final Point adjustedP = adjustLocationForClearSpace(p, size.width, size.height); - if (popupPosition == PopupPosition.CENTERED_FORCED || p.equals(adjustedP)) { + if (framePosition == PopupPosition.CENTERED_FORCED || p.equals(adjustedP)) { f.setLocation(p); - f.putClientProperty(PROPERTY_POPUP_POSITION, popupPosition); - f.putClientProperty(PROPERTY_RESIZABLE, resizable); + f.putClientProperty(PROPERTY_POPUP_POSITION, framePosition); + f.putClientProperty(PROPERTY_RESIZABLE, frameResizable); } else { f.setLocation(adjustedP); } @@ -574,10 +576,12 @@ public Dimension getMinimumSize() { f.setFrameIcon(null); f.setVisible(true); - f.setResizable(resizable); + f.setResizable(frameResizable); try { f.setSelected(true); - } catch (java.beans.PropertyVetoException e) {} + } catch (java.beans.PropertyVetoException e) { + logger.log(Level.FINE, "Frame selection vetoed.", e); + } return f; } @@ -615,8 +619,8 @@ private void addToCanvas(Component comp, Integer layer) { // To avoid illegal component position exception - remove the component first remove(comp); add(comp, layer); - } catch (Exception e) { - logger.log(Level.WARNING, "addToCanvas(" + } catch (IllegalArgumentException e) { + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "addToCanvas(" + comp.getClass().getSimpleName() + " at " + comp.getX() + "," + comp.getY() + " on layer " + layer + ") failed.", e); @@ -664,8 +668,10 @@ private boolean nothingShowing() { private Point chooseLocation(Component comp, int width, int height, PopupPosition popupPosition) { Point p = null; - if ((comp instanceof FreeColPanel) - && (p = getSavedPosition(comp)) != null) { + if (comp instanceof FreeColPanel) { + p = getSavedPosition(comp); + } + if (p != null) { // Sanity check stuff coming out of client options. if (p.getX() < 0 || p.getX() >= getWidth() - width @@ -674,7 +680,8 @@ private Point chooseLocation(Component comp, int width, int height, p = null; } } - int x = 0, y = 0; + int x = 0; + int y = 0; if (p != null) { x = (int)p.getX(); y = (int)p.getY(); @@ -715,7 +722,10 @@ private Point chooseLocation(Component comp, int width, int height, break; case UPPER_LEFT: case ORIGIN: - x = y = 0; + x = 0; + y = 0; + break; + default: break; } } @@ -724,11 +734,10 @@ private Point chooseLocation(Component comp, int width, int height, } private Point adjustLocationForClearSpace(Point location, int width, int height) { - Point p; int x = location.x; int y = location.y; - if ((p = getClearSpace(x, y, width, height, MAXTRY)) != null - && p.x >= 0 && p.x < getWidth() + Point p = getClearSpace(x, y, width, height, MAXTRY); + if (p != null && p.x >= 0 && p.x < getWidth() && p.y >= 0 && p.y < getHeight()) { x = p.x; y = p.y; @@ -753,7 +762,7 @@ private Point getClearSpace(final int x, final int y, final Rectangle bounds = this.getBounds(); if (!bounds.contains(x, y)) return null; - tries = 3 * tries + 1; // 3 new candidates per level + int remaining = 3 * tries + 1; // 3 new candidates per level List todo = new ArrayList<>(); Point p = new Point(x, y); todo.add(p); @@ -766,9 +775,10 @@ private Point getClearSpace(final int x, final int y, // Find the position with the least overlap int bestScore = Integer.MAX_VALUE; Point best = p; + Rectangle r = new Rectangle(); while (!todo.isEmpty()) { p = todo.remove(0); - Rectangle r = new Rectangle(p.x, p.y, w, h); + r.setBounds(p.x, p.y, w, h); if (!bounds.contains(r)) { continue; } @@ -796,7 +806,8 @@ private Point getClearSpace(final int x, final int y, best = p; } // Guarantee eventual completion - if (--tries <= 0) break; + remaining -= 1; + if (remaining <= 0) break; int n = todo.size(), // Some alternative new positions @@ -835,7 +846,10 @@ private Point getSavedPosition(Component comp) { if (!co.getBoolean(ClientOptions.REMEMBER_PANEL_POSITIONS)) { return null; } - } catch (Exception e) {} + } catch (IllegalArgumentException e) { + logger.log(Level.FINE, "Failed to read position option.", e); + return null; + } return co.getPanelPosition(comp.getClass().getName()); } @@ -853,7 +867,10 @@ private Dimension getSavedSize(Component comp) { if (!co.getBoolean(ClientOptions.REMEMBER_PANEL_SIZES)) { return null; } - } catch (Exception e) {} + } catch (IllegalArgumentException e) { + logger.log(Level.FINE, "Failed to read size option.", e); + return null; + } return co.getPanelSize(comp.getClass().getName()); } @@ -893,7 +910,10 @@ private void savePosition(Component comp, Point position) { try { if (!this.freeColClient.getClientOptions() .getBoolean(ClientOptions.REMEMBER_PANEL_POSITIONS)) return; - } catch (Exception e) {} + } catch (IllegalArgumentException e) { + logger.log(Level.FINE, "Failed to read position option.", e); + return; + } String className = comp.getClass().getName(); saveInteger(className, ".x", position.x); @@ -910,7 +930,10 @@ private void saveSize(Component comp, Dimension size) { try { if (!this.freeColClient.getClientOptions() .getBoolean(ClientOptions.REMEMBER_PANEL_SIZES)) return; - } catch (Exception e) {} + } catch (IllegalArgumentException e) { + logger.log(Level.FINE, "Failed to read size option.", e); + return; + } String className = comp.getClass().getName(); saveInteger(className, ".w", size.width); @@ -922,9 +945,8 @@ private void saveSize(Component comp, Dimension size) { * to be saved. * * @param c The closing {@code Component}. - * @param jif The enclosing {@code JInternalFrame}. */ - private void notifyClose(Component c, JInternalFrame jif) { + private void notifyClose(Component c) { if (c instanceof FreeColPanel) { FreeColPanel fcp = (FreeColPanel) c; fcp.firePropertyChange("closing", false, true); @@ -1111,7 +1133,7 @@ public void closePanel(String panel) { for (Component c2 : jif.getContentPane().getComponents()) { if (panel.equals(c2.getClass().getName())) { savePositionAndSize(c2, jif); - notifyClose(c2, jif); + notifyClose(c2); return; } } @@ -1256,7 +1278,9 @@ public T getExistingFreeColPanel(Class type) { }); return ret; } - } catch (ClassCastException cce) {} + } catch (ClassCastException cce) { + logger.log(Level.FINE, "Panel cast failed.", cce); + } } } } @@ -1357,12 +1381,12 @@ public void removeFromCanvas(Component comp) { // crashes here deep in the java libraries. try { super.remove(comp); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { logger.log(Level.WARNING, "Java crash", e); } } if (jif != null) { // Notify close after removing from Canvas - notifyClose(comp, jif); + notifyClose(comp); } repaint(updateBounds.x, updateBounds.y, updateBounds.width, updateBounds.height); @@ -1558,7 +1582,7 @@ public void closeMenus() { for (JInternalFrame jif : getAllFrames()) { for (Component c : jif.getContentPane().getComponents()) { savePositionAndSize(c, jif); - notifyClose(c, jif); + notifyClose(c); } jif.dispose(); } diff --git a/src/net/sf/freecol/client/gui/CanvasMapEditorMouseListener.java b/src/net/sf/freecol/client/gui/CanvasMapEditorMouseListener.java index 2afea44a9a..ccb0f652ad 100644 --- a/src/net/sf/freecol/client/gui/CanvasMapEditorMouseListener.java +++ b/src/net/sf/freecol/client/gui/CanvasMapEditorMouseListener.java @@ -103,7 +103,7 @@ public void mouseClicked(MouseEvent e) { //} else { Disabled: TODO, is this necessary? //canvas.requestFocus(); } - } catch (Exception ex) { + } catch (IllegalArgumentException | IllegalStateException ex) { logger.log(Level.WARNING, "Error in mouseClicked!", ex); } } @@ -136,7 +136,7 @@ public void mousePressed(MouseEvent e) { } } } - } catch (Exception ex) { + } catch (IllegalArgumentException | IllegalStateException ex) { logger.log(Level.WARNING, "Error in mousePressed!", ex); } } @@ -165,7 +165,10 @@ public void mouseReleased(MouseEvent e) { } // find the area to transform - int min_x, max_x, min_y, max_y; + int min_x; + int max_x; + int min_y; + int max_y; if (start.getX() < end.getX()) { min_x = start.getX(); max_x = end.getX(); @@ -182,7 +185,7 @@ public void mouseReleased(MouseEvent e) { } // apply transformation to all tiles in the area - Tile t = null; + Tile t; for (int x = min_x; x <= max_x; x++) { for (int y = min_y; y <= max_y; y++) { t = getMap().getTile(x, y); diff --git a/src/net/sf/freecol/client/gui/CanvasMouseListener.java b/src/net/sf/freecol/client/gui/CanvasMouseListener.java index dbfd6b71b2..30c9d94f62 100644 --- a/src/net/sf/freecol/client/gui/CanvasMouseListener.java +++ b/src/net/sf/freecol/client/gui/CanvasMouseListener.java @@ -47,16 +47,19 @@ public CanvasMouseListener(FreeColClient freeColClient) { /** * {@inheritDoc} */ + @Override public void mouseEntered(MouseEvent e) { /* Ignore for now. */ } /** * {@inheritDoc} */ + @Override public void mouseExited(MouseEvent e) { /* Ignore for now. */ } /** * {@inheritDoc} */ + @Override public void mousePressed(MouseEvent e) { if (!e.getComponent().isEnabled()) return; final GUI gui = getGUI(); @@ -93,6 +96,7 @@ public void mousePressed(MouseEvent e) { /** * {@inheritDoc} */ + @Override public void mouseReleased(MouseEvent e) { if (!e.getComponent().isEnabled()) return; @@ -110,6 +114,7 @@ public void mouseReleased(MouseEvent e) { /** * {@inheritDoc} */ + @Override public void mouseClicked(MouseEvent e) { if (!e.getComponent().isEnabled()) return; diff --git a/src/net/sf/freecol/client/gui/ChoiceItem.java b/src/net/sf/freecol/client/gui/ChoiceItem.java index c2b6747902..135557a6f5 100644 --- a/src/net/sf/freecol/client/gui/ChoiceItem.java +++ b/src/net/sf/freecol/client/gui/ChoiceItem.java @@ -30,7 +30,7 @@ /** * Can be used as a single choice for the - * {@link FreeColChoiceDialog}. + * {@link net.sf.freecol.client.gui.dialog.FreeColDialog}. * @param The type of the contained item. */ public class ChoiceItem implements Comparable> { diff --git a/src/net/sf/freecol/client/gui/DialogHandler.java b/src/net/sf/freecol/client/gui/DialogHandler.java index e055d82e0f..5f330b0412 100644 --- a/src/net/sf/freecol/client/gui/DialogHandler.java +++ b/src/net/sf/freecol/client/gui/DialogHandler.java @@ -24,6 +24,7 @@ * The interface for non-modal dialog handlers. * @param The type of the response. */ +@FunctionalInterface public interface DialogHandler { /** diff --git a/src/net/sf/freecol/client/gui/FontLibrary.java b/src/net/sf/freecol/client/gui/FontLibrary.java index d58ba42a84..985cb86b07 100644 --- a/src/net/sf/freecol/client/gui/FontLibrary.java +++ b/src/net/sf/freecol/client/gui/FontLibrary.java @@ -28,6 +28,7 @@ import java.util.logging.Logger; import net.sf.freecol.common.resources.ResourceManager; +import java.util.logging.Level; /** @@ -173,7 +174,7 @@ public static synchronized Font getUnscaledFont(String spec, String text) { if (displayTest(ret, text)) return ret; // Failed the display test. Try to fix these by changing the // spec at the call site. - logger.warning("Fontlibrary cached font for " + spec + if (logger.isLoggable(Level.WARNING)) logger.warning("Fontlibrary cached font for " + spec + " failed to display: " + text); } @@ -205,13 +206,13 @@ public static synchronized Font getUnscaledFont(String spec, String text) { // Fall back to the main font, we are out of options. // This is bad, because every time we try *text* we // will end up here again. Fix this warning if it happens! - logger.warning("FontLibrary found no font for: " + text); + if (logger.isLoggable(Level.WARNING)) logger.warning("FontLibrary found no font for: " + text); } ret = mainFont; } ret = ret.deriveFont(style, size.forFont()); if (ret == null) { - logger.warning("FontLibrary could not derive font for: " + spec); + if (logger.isLoggable(Level.WARNING)) logger.warning("FontLibrary could not derive font for: " + spec); } else { FontLibrary.fontCache.put(spec, ret); } diff --git a/src/net/sf/freecol/client/gui/FreeColFrame.java b/src/net/sf/freecol/client/gui/FreeColFrame.java index 6039a4ca28..4e0dd1bf3d 100644 --- a/src/net/sf/freecol/client/gui/FreeColFrame.java +++ b/src/net/sf/freecol/client/gui/FreeColFrame.java @@ -39,6 +39,7 @@ import net.sf.freecol.client.FreeColClient; import net.sf.freecol.client.gui.menu.FreeColMenuBar; import net.sf.freecol.common.option.FullscreenDisplayModeOption; +import java.util.logging.Level; /** @@ -67,6 +68,7 @@ public class FreeColFrame extends JFrame { public FreeColFrame(FreeColClient freeColClient, GraphicsDevice gd, JMenuBar menuBar, boolean windowed, Rectangle bounds) { super(getFrameName(), gd.getDefaultConfiguration()); + Rectangle frameBounds = bounds; this.freeColClient = freeColClient; setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); @@ -96,21 +98,22 @@ public FreeColFrame(FreeColClient freeColClient, GraphicsDevice gd, // Use default bounds if not windowed or (possibly deliberately) // invalid bounds specified - if (!windowed || bounds==null || bounds.width<=0 || bounds.height<=0) { - bounds = gd.getDefaultConfiguration().getBounds(); + if (!windowed || frameBounds == null + || frameBounds.width <= 0 || frameBounds.height <= 0) { + frameBounds = gd.getDefaultConfiguration().getBounds(); if (windowed) { Insets screenInsets = Toolkit.getDefaultToolkit() .getScreenInsets(gd.getDefaultConfiguration()); - bounds = new Rectangle(bounds.x + screenInsets.left, - bounds.y + screenInsets.top, - bounds.width - screenInsets.right, - bounds.height - screenInsets.bottom); + frameBounds = new Rectangle(frameBounds.x + screenInsets.left, + frameBounds.y + screenInsets.top, + frameBounds.width - screenInsets.right, + frameBounds.height - screenInsets.bottom); } } - setBounds(bounds); - logger.info(((windowed) ? "Windowed" : "Full screen") - + " frame created with size " + bounds.width - + "x" + bounds.height); + setBounds(frameBounds); + if (logger.isLoggable(Level.INFO)) logger.info(((windowed) ? "Windowed" : "Full screen") + + " frame created with size " + frameBounds.width + + "x" + frameBounds.height); /* TODO: this should do something useful! if (windowed) { addComponentListener(new ComponentAdapter() { diff --git a/src/net/sf/freecol/client/gui/GUI.java b/src/net/sf/freecol/client/gui/GUI.java index d8e6a626c9..413dfe980c 100644 --- a/src/net/sf/freecol/client/gui/GUI.java +++ b/src/net/sf/freecol/client/gui/GUI.java @@ -664,7 +664,7 @@ public TradeAction getIndianSettlementTradeChoice(Settlement settlement, boolean canSell, boolean canGift) { String msg; - ArrayList> choices = new ArrayList<>(); + List> choices = new ArrayList<>(); if (canBuy) { msg = Messages.message("tradeProposition.toBuy"); choices.add(new ChoiceItem<>(msg, TradeAction.BUY, canBuy)); @@ -1017,7 +1017,7 @@ public final void showNewPanel() { * @param sound The sound resource to play, or if null stop playing. */ public void playSound(String sound) { - if (sound != null && ResourceManager.getString(sound + ".type", "").equals("music")) { + if (sound != null && "music".equals(ResourceManager.getString(sound + ".type", ""))) { getFreeColClient().getSoundController().playMusic(sound); } else { getFreeColClient().getSoundController().playSound(sound); @@ -2044,7 +2044,7 @@ public void showDeclarationPanel(Runnable afterClosing) { } * @param spec The enclosing {@code Specification}. * @param group The {@code OptionGroup} to show. * @param editable If true, the option group can be edited. - * @return The (possibly modified) {@code OptionGroup}. + * @param dialogHandler Callback executed when the dialog gets closed. */ public void showDifficultyDialog(Specification spec, OptionGroup group, diff --git a/src/net/sf/freecol/client/gui/GrayLayer.java b/src/net/sf/freecol/client/gui/GrayLayer.java index 202b169487..a6c14d8b2d 100644 --- a/src/net/sf/freecol/client/gui/GrayLayer.java +++ b/src/net/sf/freecol/client/gui/GrayLayer.java @@ -98,8 +98,8 @@ public void paintComponent(Graphics g) { } ImageIcon coatOfArmsIcon = null; - String message = null; - Color colour = null; + String message; + Color colour; if (player == null) { message = Messages.message(freeColClient.getGame().getTurn() diff --git a/src/net/sf/freecol/client/gui/ImageLibrary.java b/src/net/sf/freecol/client/gui/ImageLibrary.java index 6f96377065..2447a66631 100644 --- a/src/net/sf/freecol/client/gui/ImageLibrary.java +++ b/src/net/sf/freecol/client/gui/ImageLibrary.java @@ -78,6 +78,7 @@ import net.sf.freecol.common.resources.StringResource; import net.sf.freecol.common.resources.Video; import net.sf.freecol.common.util.ImageUtils; +import java.util.logging.Level; /** @@ -186,7 +187,9 @@ public static PathType getPathType(Unit u) { private float scaleFactor; /** Fixed tile dimensions. */ - private Dimension tileSize, tileOverlaySize, tileForestSize; + private Dimension tileSize; + private Dimension tileOverlaySize; + private Dimension tileForestSize; /** Cache for images. */ private final ImageCache imageCache; @@ -691,7 +694,7 @@ private BufferedImage getObjectImageInternal(FreeColObject display, ? getUnitTypeImage((UnitType)derived, size) : null; if (image == null) { - logger.warning("Could not find image for " + display); + if (logger.isLoggable(Level.WARNING)) logger.warning("Could not find image for " + display); return null; } return image; @@ -755,14 +758,15 @@ public static BufferedImage getPanelBackground() { * superclass. */ public static BufferedImage getPanelBackground(Class clazz) { - while (clazz != null) { - final ImageResource ir = ResourceManager.getImageResource("image.background." + clazz.getSimpleName(), false); + Class current = clazz; + while (current != null) { + final ImageResource ir = ResourceManager.getImageResource("image.background." + current.getSimpleName(), false); if (ir != null) { return ir.getImage(); } - clazz = clazz.getSuperclass(); - if (!clazz.getName().startsWith("net.sf.freecol")) { - clazz = null; + current = current.getSuperclass(); + if (current == null || !current.getName().startsWith("net.sf.freecol")) { + current = null; } } return getPanelBackground(); @@ -885,19 +889,20 @@ private BufferedImage getScaledBuildingTypeImage(BuildingType buildingType, public Dimension determineMaxSizeUsingSizeFromAllLevels(BuildingType buildingType, Player player) { int maxWidth = 0; int maxHeight = 0; - while (buildingType.getUpgradesFrom() != null) { - buildingType = buildingType.getUpgradesFrom(); + BuildingType current = buildingType; + while (current.getUpgradesFrom() != null) { + current = current.getUpgradesFrom(); } do { - final Image buildingImage = getScaledBuildingTypeImage(buildingType, player, getScaleFactor()); + final Image buildingImage = getScaledBuildingTypeImage(current, player, getScaleFactor()); if (buildingImage.getWidth(null) > maxWidth) { maxWidth = buildingImage.getWidth(null); } if (buildingImage.getHeight(null) > maxHeight) { maxHeight = buildingImage.getHeight(null); } - buildingType = buildingType.getUpgradesTo(); - } while (buildingType != null); + current = current.getUpgradesTo(); + } while (current != null); return new Dimension(maxWidth, maxHeight); } @@ -1045,7 +1050,6 @@ public BufferedImage createColonyTitleImage(Graphics2D g2d, String title, Player if (poles && poleRight != null) { resultG2D.drawImage(poleRight, x, 0, null); } - x += eastImage.getWidth(); } x = (imageWidth - textWidth) / 2; final int textY = y + (centerImage.getHeight() - textHeight) / 2 + fm.getAscent(); @@ -1119,7 +1123,7 @@ public static BufferedImage getMonarchImage(String monarchKey) { try { int n = Integer.parseInt(monarchKey); key = getMercenaryLeaderKey(n); - } catch (Exception e) { + } catch (NumberFormatException e) { key = getMonarchKey(monarchKey); } return getUnscaledImage(key); @@ -1744,17 +1748,18 @@ public BufferedImage getTileImageWithOverlayAndForest(TileType type, private static String getUnitTypeImageKey(UnitType unitType, Player owner, String roleId, boolean nativeEthnicity) { + boolean isNativeEthnicity = nativeEthnicity; // Units that can only be native don't need the .native key part - if (nativeEthnicity + if (isNativeEthnicity && unitType.hasAbility(Ability.BORN_IN_INDIAN_SETTLEMENT)) { - nativeEthnicity = false; + isNativeEthnicity = false; } // Try to get an image matching the key String roleQual = (Role.isDefaultRoleId(roleId)) ? "" : "." + Role.getRoleIdSuffix(roleId); String key = "image.unit." + unitType.getId() + roleQual - + ((nativeEthnicity) ? ".native" : ""); - if (nativeEthnicity + + ((isNativeEthnicity) ? ".native" : ""); + if (isNativeEthnicity && ResourceManager.getImageResource(key, false) == null) { key = "image.unit." + unitType.getId() + roleQual; } @@ -2031,20 +2036,21 @@ private BufferedImage createChip(Graphics2D g, String text, */ public BufferedImage getStringImage(Graphics g, String text, Color color, Font font) { - if (color == null) { - logger.warning("getStringImage(" + text + ") called with color null"); - color = Color.WHITE; + Color textColor = color; + if (textColor == null) { + if (logger.isLoggable(Level.WARNING)) logger.warning("getStringImage(" + text + ") called with color null"); + textColor = Color.WHITE; } // Check the cache final String key = text + "." + font.getFontName().replace(' ', '-') + "." + Integer.toString(font.getSize()) - + "." + Integer.toHexString(color.getRGB()); + + "." + Integer.toHexString(textColor.getRGB()); BufferedImage img = this.stringImageCache.get(key); if (img != null) return img; - img = createStringImage(text, color, font, g.getFontMetrics(font)); + img = createStringImage(text, textColor, font, g.getFontMetrics(font)); this.stringImageCache.put(key, img); return img; } @@ -2075,7 +2081,9 @@ private BufferedImage createStringImage(String text, Color color, // draw the border around letters int borderWidth = 1; int borderColor = makeStringBorderColor(color).getRGB(); - int srcRGB, dstRGB, srcA; + int srcRGB; + int dstRGB; + int srcA; for (int biY = 0; biY < height; biY++) { for (int biX = borderWidth; biX < width - borderWidth; biX++) { int biXI = width - biX - 1; diff --git a/src/net/sf/freecol/client/gui/ScrollThread.java b/src/net/sf/freecol/client/gui/ScrollThread.java index 66298cf5fe..33e08e1078 100644 --- a/src/net/sf/freecol/client/gui/ScrollThread.java +++ b/src/net/sf/freecol/client/gui/ScrollThread.java @@ -20,6 +20,7 @@ package net.sf.freecol.client.gui; import java.util.logging.Level; +import java.lang.reflect.InvocationTargetException; import java.util.logging.Logger; import javax.swing.SwingUtilities; @@ -110,7 +111,7 @@ private void normalScrolling(final GUI gui) { return; } }); - } catch (Exception ex) { + } catch (InterruptedException | InvocationTargetException ex) { logger.log(Level.WARNING, "Exception while scrolling", ex); abort(); break; diff --git a/src/net/sf/freecol/client/gui/SwingGUI.java b/src/net/sf/freecol/client/gui/SwingGUI.java index b17dbdb531..c5a0b4751a 100644 --- a/src/net/sf/freecol/client/gui/SwingGUI.java +++ b/src/net/sf/freecol/client/gui/SwingGUI.java @@ -37,6 +37,7 @@ import java.awt.image.BufferedImage; import java.beans.PropertyChangeEvent; import java.io.File; +import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -232,7 +233,7 @@ public SwingGUI(FreeColClient freeColClient) { configureMigLayout(scaleFactor); - logger.info("GUI constructed using scale factor " + scaleFactor); + if (logger.isLoggable(Level.INFO)) logger.info("GUI constructed using scale factor " + scaleFactor); } @@ -503,11 +504,11 @@ public void toggleRangedAttackMode() { private boolean changeSelectedTile(Tile newTile, boolean refocus) { final Tile oldTile = getSelectedTile(); final Tile oldFocus = getFocus(); - refocus = newTile != null + boolean shouldRefocus = newTile != null && newTile != oldFocus && (oldFocus == null || refocus || !this.mapViewer.getMapViewerBounds().onScreen(newTile)); - if (refocus) setFocus(newTile); + if (shouldRefocus) setFocus(newTile); if (newTile == oldTile) return false; this.mapViewer.getMapViewerState().setSelectedTile(newTile); if (oldTile != null) refreshTile(oldTile); @@ -579,7 +580,7 @@ private void updateUnitPath() { && !active.isAtLocation(destination)) { try { path = active.findPath(destination); - } catch (Exception e) { + } catch (IllegalStateException e) { logger.log(Level.WARNING, "Path fail", e); active.setDestination(null); } @@ -756,7 +757,7 @@ public void invokeNowOrWait(Runnable runnable) { } else { try { SwingUtilities.invokeAndWait(runnable); - } catch (Exception ex) { + } catch (InterruptedException | InvocationTargetException ex) { logger.log(Level.WARNING, "Client GUI interaction", ex); } } @@ -820,20 +821,21 @@ public void reconnectGUI(Unit active, Tile tile) { resetMapZoom(); // This should refresh the map // Update the view, somehow. Try really hard to find a tile // to focus on + Tile focusTile = tile; if (active != null) { changeView(active, false); if (active.hasTile()) { - tile = active.getTile(); + focusTile = active.getTile(); } else if (active.getOwner().getFallbackTile() != null) { - tile = active.getOwner().getFallbackTile(); - changeView(tile); + focusTile = active.getOwner().getFallbackTile(); + changeView(focusTile); } - } else if (tile != null) { - changeView(tile); + } else if (focusTile != null) { + changeView(focusTile); } else { changeView((Unit)null, false); } - this.mapViewer.getMapViewerBounds().setFocus(tile); + this.mapViewer.getMapViewerBounds().setFocus(focusTile); enableMapControls(false); enableMapControls(getGame() != null && getGame().getMap() != null && getClientOptions().getBoolean(ClientOptions.DISPLAY_MAP_CONTROLS)); @@ -891,7 +893,7 @@ public void startGUI(final Dimension desiredWindowSize) { opts.getOption(ClientOptions.LANGUAGE, LanguageOption.class) .addPropertyChangeListener((PropertyChangeEvent e) -> { Language language = (Language)e.getNewValue(); - logger.info("Set language to: " + language); + if (logger.isLoggable(Level.INFO)) logger.info("Set language to: " + language); if (Messages.AUTOMATIC.equalsIgnoreCase(language.getKey())) { showInformationPanel("info.autodetectLanguageSelected"); } else { @@ -1541,10 +1543,10 @@ public void zoomOutMap() { } private void changeMapScale(float newScale) { - newScale = constrainToMaxMapScale(newScale); + float adjustedScale = constrainToMaxMapScale(newScale); imageCache.clear(); if (this.mapViewer != null) { - this.mapViewer.changeScale(newScale); + this.mapViewer.changeScale(adjustedScale); } if (this.mapControls != null) { this.mapControls.updateMinimap(); @@ -1555,10 +1557,11 @@ private void changeMapScale(float newScale) { } private float constrainToMaxMapScale(float newScale) { - if (newScale > getMaxScale()) { - newScale = getMaxScale(); + float adjustedScale = newScale; + if (adjustedScale > getMaxScale()) { + adjustedScale = getMaxScale(); } - return newScale; + return adjustedScale; } /** @@ -1617,7 +1620,7 @@ public void clickAt(int count, int x, int y) { final Tile tile = tileAt(x, y); if (tile == null) return; - Unit other = null; + Unit other; if (!tile.isExplored()) { // Select unexplored tiles setFocus(tile); @@ -1633,36 +1636,39 @@ public void clickAt(int count, int x, int y) { } else if (settlement instanceof IndianSettlement) { showIndianSettlementPanel((IndianSettlement)settlement); } - } else if ((other = this.mapViewer.getMapViewerState().findUnitInFront(tile)) != null) { - if (getMyPlayer().owns(other)) { - // If there is one of the player units present, select it, - // unless we are on the same tile as the active unit, - // in which case select the active unit if not in units mode - // otherwise the unit *after* the active. - final Unit active = getActiveUnit(); - if (active != null && active.getTile() == tile) { - if (getViewMode() != ViewMode.MOVE_UNITS) { - other = active; - } else { - List units = tile.getUnitList(); - while (!units.isEmpty()) { - Unit u = units.remove(0); - if (u == active) { - if (!units.isEmpty()) other = units.remove(0); - break; + } else { + other = this.mapViewer.getMapViewerState().findUnitInFront(tile); + if (other != null) { + if (getMyPlayer().owns(other)) { + // If there is one of the player units present, select it, + // unless we are on the same tile as the active unit, + // in which case select the active unit if not in units mode + // otherwise the unit *after* the active. + final Unit active = getActiveUnit(); + if (active != null && active.getTile() == tile) { + if (getViewMode() != ViewMode.MOVE_UNITS) { + other = active; + } else { + List units = tile.getUnitList(); + while (!units.isEmpty()) { + Unit u = units.remove(0); + if (u == active) { + if (!units.isEmpty()) other = units.remove(0); + break; + } } } } + changeView(other, false); + } else { // Select the tile under the unit if it is not ours + setFocus(tile); + } + } else { // Otherwise select the tile in terrain mode on multiclick + if (count > 1) { + changeView(tile); + } else { + setFocus(tile); } - changeView(other, false); - } else { // Select the tile under the unit if it is not ours - setFocus(tile); - } - } else { // Otherwise select the tile in terrain mode on multiclick - if (count > 1) { - changeView(tile); - } else { - setFocus(tile); } } } @@ -1867,7 +1873,9 @@ public void updateEuropeanSubpanels() { // introspection try { Introspector.invokeVoidMethod(p, "update"); - } catch (Exception e) { + } catch (IllegalAccessException + | InvocationTargetException + | NoSuchMethodException e) { ; // "can not happen" } } @@ -2008,7 +2016,7 @@ private int determineMainFontSizeUsingClientOptions(final int dpi) { if (getClientOptions().getBoolean(ClientOptions.MANUAL_MAIN_FONT_SIZE)) { final int fontSize = getClientOptions().getInteger(ClientOptions.MAIN_FONT_SIZE); - logger.info("Manual font size: " + fontSize + " (reported DPI: " + dpi + ")"); + if (logger.isLoggable(Level.INFO)) logger.info("Manual font size: " + fontSize + " (reported DPI: " + dpi + ")"); return fontSize; } @@ -2017,7 +2025,7 @@ private int determineMainFontSizeUsingClientOptions(final int dpi) { final int fontSizeUsingScaling = (int) (FontLibrary.DEFAULT_UNSCALED_MAIN_FONT_SIZE * scaleFactor); if (displayScaling != 0) { - logger.info("Font size based on manual display scaling: " + fontSizeUsingScaling + " (reported DPI: " + dpi + ")"); + if (logger.isLoggable(Level.INFO)) logger.info("Font size based on manual display scaling: " + fontSizeUsingScaling + " (reported DPI: " + dpi + ")"); return fontSizeUsingScaling; } @@ -2030,11 +2038,11 @@ private int determineMainFontSizeUsingClientOptions(final int dpi) { } if (fontSizeUsingDpi >= fontSizeUsingScaling * 0.25f) { - logger.info("Using font size from scaling: " + fontSizeUsingScaling + " (reported DPI: " + dpi + ", screen height: " + screenHeight + ")"); + if (logger.isLoggable(Level.INFO)) logger.info("Using font size from scaling: " + fontSizeUsingScaling + " (reported DPI: " + dpi + ", screen height: " + screenHeight + ")"); return fontSizeUsingScaling; } - logger.info("Automatic font size: " + fontSizeUsingDpi + " (reported DPI: " + dpi + ", screen height: " + screenHeight + ")"); + if (logger.isLoggable(Level.INFO)) logger.info("Automatic font size: " + fontSizeUsingDpi + " (reported DPI: " + dpi + ", screen height: " + screenHeight + ")"); return Math.max(10, fontSizeUsingDpi); } @@ -2073,10 +2081,10 @@ private float determineScaleFactorUsingClientOptions(final int dpi) { scaleFactor = Math.min(1.75F, scaleFactor); } - logger.info("Automatic scale factor: " + scaleFactor + " (reported DPI: " + dpi + ", screen height: " + screenHeight + ")"); + if (logger.isLoggable(Level.INFO)) logger.info("Automatic scale factor: " + scaleFactor + " (reported DPI: " + dpi + ", screen height: " + screenHeight + ")"); } else { scaleFactor = displayScaling / 100f; - logger.info("Manual scale factor: " + scaleFactor + " (reported DPI: " + dpi + ")"); + if (logger.isLoggable(Level.INFO)) logger.info("Manual scale factor: " + scaleFactor + " (reported DPI: " + dpi + ")"); } return scaleFactor; } @@ -2094,8 +2102,8 @@ public FreeColPanel showColonyPanel(final Colony colony, Unit unit) { if (panel == null) { try { panel = new ColonyPanel(getFreeColClient(), colony); - } catch (Exception e) { - logger.log(Level.WARNING, "Exception in ColonyPanel for " + } catch (IllegalStateException e) { + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Exception in ColonyPanel for " + colony.getId(), e); return null; } @@ -2172,7 +2180,7 @@ public void showDeclarationPanel(Runnable afterClosing) { refresh(); afterClosing.run(); }); - } catch (RuntimeException e) { + } catch (IllegalArgumentException | IllegalStateException e) { mapViewer.getMapViewerRepaintManager().setRepaintsBlocked(false); throw e; } @@ -2489,7 +2497,7 @@ public void showNegotiationDialog(FreeColGameObject our, FreeColGameObject other public FreeColPanel showNewPanel(Specification spec) { try { return this.widgets.showNewPanel(spec); - } catch (RuntimeException e) { + } catch (IllegalArgumentException | IllegalStateException e) { logger.log(Level.WARNING, "Exception while showing new game panel", e); showErrorPanel(e, StringTemplate.key("error.unspecified")); return null; @@ -2548,7 +2556,7 @@ public FreeColPanel showReportColonyPanel() { compact = getFreeColClient().getClientOptions() .getInteger(ClientOptions.COLONY_REPORT) == ClientOptions.COLONY_REPORT_COMPACT; - } catch (Exception e) { + } catch (IllegalArgumentException e) { compact = false; } return this.widgets.showReportColonyPanel(compact); diff --git a/src/net/sf/freecol/client/gui/TilePopup.java b/src/net/sf/freecol/client/gui/TilePopup.java index 89236998f2..b77c779e24 100644 --- a/src/net/sf/freecol/client/gui/TilePopup.java +++ b/src/net/sf/freecol/client/gui/TilePopup.java @@ -130,7 +130,7 @@ public TilePopup(final FreeColClient freeColClient, final Tile tile) { } // Add state changes if present - JMenuItem ji = null; + JMenuItem ji; if (activeUnit.checkSetState(UnitState.ACTIVE)) { ji = Utility.localizedMenuItem("activateUnit"); ji.addActionListener((ActionEvent ae) -> { diff --git a/src/net/sf/freecol/client/gui/Widgets.java b/src/net/sf/freecol/client/gui/Widgets.java index 3b0d5c226e..fa5ee37f26 100644 --- a/src/net/sf/freecol/client/gui/Widgets.java +++ b/src/net/sf/freecol/client/gui/Widgets.java @@ -26,6 +26,8 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; import javax.swing.ButtonGroup; import javax.swing.ImageIcon; @@ -155,6 +157,8 @@ */ public final class Widgets { + private static final Logger logger = Logger.getLogger(Widgets.class.getName()); + /** The game client. */ private final FreeColClient freeColClient; @@ -325,25 +329,33 @@ private FreeColDialog createChoiceDialog(StringTemplate tmpl, ImageIcon i int i = 0; boolean sameSize = allChoices.size() > 4; + StringBuilder layoutBuilder = new StringBuilder(32); for (ChoiceItem ci : allChoices) { final JButton button = createButtonFromChoiceItem(api, ci); - List layout = new ArrayList<>(); + layoutBuilder.setLength(0); + boolean hasLayout = false; if (i % choiceWrap == 0) { - layout.add("newline, split " + choiceWrap); + layoutBuilder.append("newline, split ").append(choiceWrap); + hasLayout = true; } if (sameSize) { - layout.add("sg"); + if (hasLayout) layoutBuilder.append(", "); + layoutBuilder.append("sg"); + hasLayout = true; } else { if (ci.isOK()) { - layout.add("tag ok"); + if (hasLayout) layoutBuilder.append(", "); + layoutBuilder.append("tag ok"); + hasLayout = true; } if (ci.isCancel()) { - layout.add("tag cancel"); + if (hasLayout) layoutBuilder.append(", "); + layoutBuilder.append("tag cancel"); + hasLayout = true; } } - final String layoutStr = layout.stream().reduce((a, b) -> a + ", " + b).orElse(null); - content.add(button, layoutStr); + content.add(button, hasLayout ? layoutBuilder.toString() : null); i++; } @@ -588,7 +600,6 @@ public void showDeclarationPanel(Runnable afterClosing) { * @param group The {@code OptionGroup} containing the difficulty. * @param editable If the options should be editable. * @param dialogHandler Callback executed when the dialog gets closed. - * @return The resulting {@code OptionGroup}. */ public void showDifficultyDialog(Specification spec, OptionGroup group, @@ -684,7 +695,6 @@ public void showEmigrationDialog(Player player, boolean fountainOfYouth, DialogH * Show the EndTurnDialog with given units that could still move. * * @param units A list of {@code Unit}s that could still move. - * @param handler A {@code DialogHandler} for the dialog response. */ public void showEndTurnDialog(List units) { final EndTurnDialog endTurnPanel = new EndTurnDialog(this.freeColClient, units); @@ -841,7 +851,7 @@ public FreeColPanel showInformationPanel(FreeColObject displayObject, * @param filters {@code FileFilter}s for suitable files. * @return The selected {@code File}. */ - public File showLoadDialog(File directory, FileFilter[] filters) { + public File showLoadDialog(File directory, FileFilter... filters) { LoadDialog dialog = new LoadDialog(this.freeColClient, getFrame(), directory, filters); @@ -852,7 +862,7 @@ public File showLoadDialog(File directory, FileFilter[] filters) { * Show a dialog for setting options when loading a savegame. * * The settings can be retrieved directly from - * {@link LoadingSavegameDialog} after calling this method. + * {@link LoadingSavegameInfo} after calling this method. * * @param pubSer Default value. * @param single Default value. @@ -1234,7 +1244,9 @@ public int showSelectTributeAmountDialog(StringTemplate question, int maximum) { int result = -1; try { result = Integer.parseInt(resultString); - } catch (NumberFormatException nfe) {} + } catch (NumberFormatException nfe) { + if (logger.isLoggable(Level.FINE)) logger.log(Level.FINE, "Invalid tribute amount: " + resultString, nfe); + } return (result <= 0 || result > maximum) ? null : result; } @@ -1327,7 +1339,7 @@ public void showVictoryDialog(DialogHandler handler) { * Run out of ColonyPanel, so the tile is already displayed. * * @param colony The {@code Colony} to display. - * @return The response returned by the dialog. + * @param handler A {@code DialogHandler} for the dialog response. */ public void showWarehouseDialog(Colony colony, DialogHandler handler) { final WarehouseDialog dialog = new WarehouseDialog(this.freeColClient, colony, handler); diff --git a/src/net/sf/freecol/client/gui/action/DisplayTileTextAction.java b/src/net/sf/freecol/client/gui/action/DisplayTileTextAction.java index 6e4428e36f..b04de53bd2 100644 --- a/src/net/sf/freecol/client/gui/action/DisplayTileTextAction.java +++ b/src/net/sf/freecol/client/gui/action/DisplayTileTextAction.java @@ -53,7 +53,7 @@ public String getKey() { KeyEvent.VK_R }; - private DisplayText display = null; + private DisplayText display; /** diff --git a/src/net/sf/freecol/client/gui/action/FreeColAction.java b/src/net/sf/freecol/client/gui/action/FreeColAction.java index 009dbc3983..6ed41507a5 100644 --- a/src/net/sf/freecol/client/gui/action/FreeColAction.java +++ b/src/net/sf/freecol/client/gui/action/FreeColAction.java @@ -48,6 +48,7 @@ import net.sf.freecol.common.model.Game; import net.sf.freecol.common.model.Map; import net.sf.freecol.common.option.Option; +import java.util.logging.Level; /** @@ -274,7 +275,9 @@ public void updateRegisteredImageIcons() { } private void updateImageIcon(String key) { - final ImageLibrary lib = getGUI().getFixedImageLibrary(); + final GUI gui = getGUI(); + if (gui == null) return; + final ImageLibrary lib = gui.getFixedImageLibrary(); List images = lib.getButtonImages(key); orderButtonImageCount = images.size(); if (hasOrderButtons()) { @@ -283,7 +286,7 @@ private void updateImageIcon(String key) { putValue(BUTTON_PRESSED_IMAGE, new ImageIcon(images.remove(0))); putValue(BUTTON_DISABLED_IMAGE, new ImageIcon(images.remove(0))); } else { - logger.warning("Found only " + orderButtonImageCount + if (logger.isLoggable(Level.WARNING)) logger.warning("Found only " + orderButtonImageCount + " order button images for " + getId() + "/" + key); } } @@ -478,7 +481,9 @@ public void readFromXML(FreeColXMLReader xr) throws XMLStreamException { } /** - * {@inheritDoc} + * Gets the XML tag name for serialization. + * + * @return The XML tag name. */ public String getXMLTagName() { return TAG; } diff --git a/src/net/sf/freecol/client/gui/action/MapControlsAction.java b/src/net/sf/freecol/client/gui/action/MapControlsAction.java index 63bd09a57c..0cca13661d 100644 --- a/src/net/sf/freecol/client/gui/action/MapControlsAction.java +++ b/src/net/sf/freecol/client/gui/action/MapControlsAction.java @@ -47,14 +47,6 @@ public MapControlsAction(FreeColClient freeColClient) { // Override FreeColAction - /** - * {@inheritDoc} - */ - @Override - public void update() { - super.update(); - } - /** * {@inheritDoc} */ diff --git a/src/net/sf/freecol/client/gui/action/MiniMapToggleFogOfWarAction.java b/src/net/sf/freecol/client/gui/action/MiniMapToggleFogOfWarAction.java index 9d46cef6af..3ebf0c8469 100644 --- a/src/net/sf/freecol/client/gui/action/MiniMapToggleFogOfWarAction.java +++ b/src/net/sf/freecol/client/gui/action/MiniMapToggleFogOfWarAction.java @@ -50,6 +50,7 @@ public MiniMapToggleFogOfWarAction(FreeColClient freeColClient) { * @param freeColClient The {@code FreeColClient} for the game. * @param b a {@code boolean} value */ + @SuppressWarnings("PMD.UnusedFormalParameter") public MiniMapToggleFogOfWarAction(FreeColClient freeColClient, boolean b) { super(freeColClient, id + ".secondary"); @@ -82,4 +83,3 @@ private void updateIcons() { } } } - diff --git a/src/net/sf/freecol/client/gui/action/MiniMapToggleViewAction.java b/src/net/sf/freecol/client/gui/action/MiniMapToggleViewAction.java index 53e4c652e3..d7fdd42d2b 100644 --- a/src/net/sf/freecol/client/gui/action/MiniMapToggleViewAction.java +++ b/src/net/sf/freecol/client/gui/action/MiniMapToggleViewAction.java @@ -50,6 +50,7 @@ public MiniMapToggleViewAction(FreeColClient freeColClient) { * @param freeColClient The {@code FreeColClient} for the game. * @param b a {@code boolean} value */ + @SuppressWarnings("PMD.UnusedFormalParameter") public MiniMapToggleViewAction(FreeColClient freeColClient, boolean b) { super(freeColClient, id + ".secondary"); diff --git a/src/net/sf/freecol/client/gui/action/MiniMapZoomInAction.java b/src/net/sf/freecol/client/gui/action/MiniMapZoomInAction.java index a0ba283a0e..6ae1258ddb 100644 --- a/src/net/sf/freecol/client/gui/action/MiniMapZoomInAction.java +++ b/src/net/sf/freecol/client/gui/action/MiniMapZoomInAction.java @@ -40,6 +40,7 @@ public class MiniMapZoomInAction extends MapboardAction { public MiniMapZoomInAction(FreeColClient freeColClient) { super(freeColClient, id); + setCanvasKeyBinding(true); addImageIcons("zoom_in"); } @@ -49,9 +50,11 @@ public MiniMapZoomInAction(FreeColClient freeColClient) { * @param freeColClient The {@code FreeColClient} for the game. * @param b a {@code boolean} value */ + @SuppressWarnings("PMD.UnusedFormalParameter") public MiniMapZoomInAction(FreeColClient freeColClient, boolean b) { super(freeColClient, id + ".secondary"); + setCanvasKeyBinding(true); addImageIcons("zoom_in"); } diff --git a/src/net/sf/freecol/client/gui/action/MiniMapZoomOutAction.java b/src/net/sf/freecol/client/gui/action/MiniMapZoomOutAction.java index e1f5fa3bd8..155d9956f8 100644 --- a/src/net/sf/freecol/client/gui/action/MiniMapZoomOutAction.java +++ b/src/net/sf/freecol/client/gui/action/MiniMapZoomOutAction.java @@ -40,6 +40,7 @@ public class MiniMapZoomOutAction extends MapboardAction { public MiniMapZoomOutAction(FreeColClient freeColClient) { super(freeColClient, id); + setCanvasKeyBinding(true); addImageIcons("zoom_out"); } @@ -49,9 +50,11 @@ public MiniMapZoomOutAction(FreeColClient freeColClient) { * @param freeColClient The {@code FreeColClient} for the game. * @param b A boolean. */ + @SuppressWarnings("PMD.UnusedFormalParameter") public MiniMapZoomOutAction(FreeColClient freeColClient, boolean b) { super(freeColClient, id + ".secondary"); + setCanvasKeyBinding(true); addImageIcons("zoom_out"); } diff --git a/src/net/sf/freecol/client/gui/action/MoveAction.java b/src/net/sf/freecol/client/gui/action/MoveAction.java index 6feb91cc09..c7a8942b0c 100644 --- a/src/net/sf/freecol/client/gui/action/MoveAction.java +++ b/src/net/sf/freecol/client/gui/action/MoveAction.java @@ -58,11 +58,13 @@ public MoveAction(FreeColClient freeColClient, Direction direction) { * @param direction The {@code Direction} to move in. * @param secondary a {@code boolean} value */ + @SuppressWarnings("PMD.UnusedFormalParameter") public MoveAction(FreeColClient freeColClient, Direction direction, boolean secondary) { super(freeColClient, id + direction + ".secondary"); this.direction = direction; + setCanvasKeyBinding(true); } diff --git a/src/net/sf/freecol/client/gui/action/SelectableOptionAction.java b/src/net/sf/freecol/client/gui/action/SelectableOptionAction.java index 55af7c59ac..0ed7aa9dde 100644 --- a/src/net/sf/freecol/client/gui/action/SelectableOptionAction.java +++ b/src/net/sf/freecol/client/gui/action/SelectableOptionAction.java @@ -61,8 +61,8 @@ public final boolean getOption() { if (co != null && optionId != null) { try { return co.getBoolean(optionId); - } catch (Exception e) { - logger.log(Level.WARNING, "Failure with option: " + optionId, e); + } catch (IllegalArgumentException e) { + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Failure with option: " + optionId, e); } } return false; diff --git a/src/net/sf/freecol/client/gui/animation/Animations.java b/src/net/sf/freecol/client/gui/animation/Animations.java index 0d165ab1c4..b49842b883 100644 --- a/src/net/sf/freecol/client/gui/animation/Animations.java +++ b/src/net/sf/freecol/client/gui/animation/Animations.java @@ -27,6 +27,7 @@ import net.sf.freecol.common.model.Direction; import net.sf.freecol.common.model.Tile; import net.sf.freecol.common.model.Unit; +import java.util.logging.Level; /** @@ -40,6 +41,7 @@ public class Animations { * Trivial wrapper for zero-argument-zero-return function, * used as a callback for an animation to trigger painting. */ + @FunctionalInterface public interface Procedure { public void execute(); }; @@ -95,7 +97,7 @@ public static List unitAttack(FreeColClient freeColClient, List ret = new ArrayList<>(); Direction dirn = attackerTile.getDirection(defenderTile); if (dirn == null) { - logger.warning("Attack animation null direction: " + attacker + if (logger.isLoggable(Level.WARNING)) logger.warning("Attack animation null direction: " + attacker + " v " + defender); return ret; // Fail fast } @@ -105,7 +107,7 @@ public static List unitAttack(FreeColClient freeColClient, = UnitImageAnimation.build(attacker, attackerTile, dirn, getAttackAnimationBase(attacker), scale); if (a == null) { - logger.warning("No attack animation for: " + if (logger.isLoggable(Level.WARNING)) logger.warning("No attack animation for: " + attacker + " (" + dirn + ")"); } else { ret.add(a); @@ -119,7 +121,7 @@ public static List unitAttack(FreeColClient freeColClient, = UnitImageAnimation.build(defender, defenderTile, revd, getAttackAnimationBase(defender), scale); if (a == null) { - logger.warning("No attack animation for: " + if (logger.isLoggable(Level.WARNING)) logger.warning("No attack animation for: " + defender + " (" + revd + ")"); } else { ret.add(a); diff --git a/src/net/sf/freecol/client/gui/animation/UnitImageAnimation.java b/src/net/sf/freecol/client/gui/animation/UnitImageAnimation.java index 57d350ad03..061f4fd70a 100644 --- a/src/net/sf/freecol/client/gui/animation/UnitImageAnimation.java +++ b/src/net/sf/freecol/client/gui/animation/UnitImageAnimation.java @@ -122,6 +122,8 @@ private synchronized static List trialDirections(Direction direction) a.add(d.rotate(1)); a.add(d.rotate(-1)); a.add(d.rotate(2)); a.add(d.rotate(-2)); break; + default: + break; } alternatives.put(d, a); } diff --git a/src/net/sf/freecol/client/gui/animation/UnitMoveAnimation.java b/src/net/sf/freecol/client/gui/animation/UnitMoveAnimation.java index f3874abab6..6b39de50fb 100644 --- a/src/net/sf/freecol/client/gui/animation/UnitMoveAnimation.java +++ b/src/net/sf/freecol/client/gui/animation/UnitMoveAnimation.java @@ -89,7 +89,8 @@ public void executeWithLabel(JLabel unitLabel, * movementRatio); Point point = srcPoint; - long time = now(), dropFrames = 0; + long time = now(); + long dropFrames = 0; while (!point.equals(dstPoint)) { point.x += stepX; point.y += stepY; diff --git a/src/net/sf/freecol/client/gui/dialog/DeprecatedFreeColDialog.java b/src/net/sf/freecol/client/gui/dialog/DeprecatedFreeColDialog.java index 9431991302..b5a6f1096d 100644 --- a/src/net/sf/freecol/client/gui/dialog/DeprecatedFreeColDialog.java +++ b/src/net/sf/freecol/client/gui/dialog/DeprecatedFreeColDialog.java @@ -131,7 +131,10 @@ public DeprecatedFreeColDialog(FreeColClient freeColClient, JFrame frame, * @return The option to select initially. */ private int selectDefault(List> options) { - int def = -1, can = -1, ok = -1, i = 0; + int def = -1; + int can = -1; + int ok = -1; + int i = 0; for (ChoiceItem ci : options) { if (ci.isDefault()) def = i; else if (ci.isCancel()) can = i; @@ -196,7 +199,7 @@ protected final void initializeDialog(JFrame frame, DialogType type, setSubcomponentsNotOpaque(this.pane); try { // Layout failures might not get logged. pack(); - } catch (Exception e) { + } catch (IllegalStateException e) { logger.log(Level.WARNING, "Packing failure", e); } setLocationRelativeTo(frame); diff --git a/src/net/sf/freecol/client/gui/dialog/EndTurnDialog.java b/src/net/sf/freecol/client/gui/dialog/EndTurnDialog.java index d5f6c12175..b3cbb52bea 100644 --- a/src/net/sf/freecol/client/gui/dialog/EndTurnDialog.java +++ b/src/net/sf/freecol/client/gui/dialog/EndTurnDialog.java @@ -187,6 +187,7 @@ public UnitCellRenderer() { } + @Override public Component getListCellRendererComponent(JList list, UnitWrapper value, int index, boolean isSelected, boolean cellHasFocus) { final JLabel imageLabel = new JLabel(); diff --git a/src/net/sf/freecol/client/gui/dialog/Flag.java b/src/net/sf/freecol/client/gui/dialog/Flag.java index 39542be244..fdaba2305a 100644 --- a/src/net/sf/freecol/client/gui/dialog/Flag.java +++ b/src/net/sf/freecol/client/gui/dialog/Flag.java @@ -522,8 +522,6 @@ public BufferedImage getImage() { case PER_SALTIRE: drawPerSaltire(g); break; - default: - break; } // draw decoration @@ -555,8 +553,6 @@ public BufferedImage getImage() { decorationShape.append(getBend(false), false); decorationShape.append(getCross(Decoration.CROSS), false); break; - default: - break; } if (decorationShape != null) { g.setColor(decorationColor); @@ -647,9 +643,9 @@ private GeneralPath getUnionTriangle(boolean isosceles) { || decoration == Decoration.BEND || decoration == Decoration.BEND_SINISTER); - double x = 0; - double y = 0; - double r = 0; + double x; + double y; + double r; if (unionShape == UnionShape.CHEVRON) { x = CHEVRON_X; y = HEIGHT; diff --git a/src/net/sf/freecol/client/gui/dialog/FreeColDialog.java b/src/net/sf/freecol/client/gui/dialog/FreeColDialog.java index 4fc567db03..1cf1365aa7 100644 --- a/src/net/sf/freecol/client/gui/dialog/FreeColDialog.java +++ b/src/net/sf/freecol/client/gui/dialog/FreeColDialog.java @@ -53,11 +53,13 @@ public FreeColDialog(DialogContentCreator dialogContentCreator) { /** - * This method is called by {@link FreeColOptionPaneUI} in order to + * This method is called by + * {@link net.sf.freecol.client.gui.plaf.FreeColOptionPaneUI} in order to * render the custom panel for modal dialogs. * - * @param api The API provided by {@link FreeColOptionPaneUI} to access - * functionality provided by JOptionPane. + * @param api The API provided by + * {@link net.sf.freecol.client.gui.plaf.FreeColOptionPaneUI} to access + * functionality provided by {@code JOptionPane}. * @return The panel to be rendered. */ public JPanel createContent(DialogApi api) { @@ -69,6 +71,7 @@ public JPanel createContent(DialogApi api) { * A content creator for the dialog. * @param The return type of the dialog. */ + @FunctionalInterface public interface DialogContentCreator { /** @@ -82,7 +85,7 @@ public interface DialogContentCreator { /** * Access to to behavior that for modal dialogs are handled in - * {@code FreeColOptionPaneUI}. + * {@link net.sf.freecol.client.gui.plaf.FreeColOptionPaneUI}. * * @param The return type of the dialog. */ diff --git a/src/net/sf/freecol/client/gui/dialog/LoadDialog.java b/src/net/sf/freecol/client/gui/dialog/LoadDialog.java index 0848b92e64..f4283736e4 100644 --- a/src/net/sf/freecol/client/gui/dialog/LoadDialog.java +++ b/src/net/sf/freecol/client/gui/dialog/LoadDialog.java @@ -50,7 +50,7 @@ public final class LoadDialog extends DeprecatedFreeColDialog { * @param fileFilters The available file filters in the dialog. */ public LoadDialog(FreeColClient freeColClient, JFrame frame, - File directory, FileFilter[] fileFilters) { + File directory, FileFilter... fileFilters) { super(freeColClient, frame); final JFileChooser fileChooser = new JFileChooser(directory); diff --git a/src/net/sf/freecol/client/gui/dialog/MapGeneratorOptionsDialog.java b/src/net/sf/freecol/client/gui/dialog/MapGeneratorOptionsDialog.java index e082b56fb5..1351570d41 100644 --- a/src/net/sf/freecol/client/gui/dialog/MapGeneratorOptionsDialog.java +++ b/src/net/sf/freecol/client/gui/dialog/MapGeneratorOptionsDialog.java @@ -144,7 +144,7 @@ private JButton makeMapButton(File file) { try { savegame = new FreeColSavegameFile(file); } catch (IOException ioe) { - logger.log(Level.WARNING, "Failed to make save game for: " + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Failed to make save game for: " + mapName, ioe); return null; } @@ -153,7 +153,7 @@ private JButton makeMapButton(File file) { try { thumbnail = ImageIO.read(savegame.getThumbnailInputStream()); } catch (IOException ioe) { - logger.log(Level.WARNING, "Failed to read thumbnail for: " + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Failed to read thumbnail for: " + mapName, ioe); thumbnail = null; } @@ -169,7 +169,7 @@ private JButton makeMapButton(File file) { + "\u00D7" + properties.getProperty("map.height")); } catch (IOException ioe) { - logger.log(Level.WARNING, "Failed to read properties for: " + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Failed to read properties for: " + mapName, ioe); } } @@ -199,7 +199,7 @@ protected boolean save(File file) { getGroup().setInteger(EDGE, getGroup().getIntegerMinimum(EDGE)); return false; } - } catch (Exception ex) { + } catch (IllegalArgumentException ex) { logger.log(Level.WARNING, "Options in disarray", ex); } if (!ok) { diff --git a/src/net/sf/freecol/client/gui/dialog/MapSizeDialog.java b/src/net/sf/freecol/client/gui/dialog/MapSizeDialog.java index cd12ca6618..bf31107405 100644 --- a/src/net/sf/freecol/client/gui/dialog/MapSizeDialog.java +++ b/src/net/sf/freecol/client/gui/dialog/MapSizeDialog.java @@ -87,7 +87,8 @@ public static FreeColDialog create() { } private static Dimension determineResult(JTextField inputWidth, JTextField inputHeight) { - int width, height; + int width; + int height; try { width = Integer.parseInt(inputWidth.getText()); height = Integer.parseInt(inputHeight.getText()); diff --git a/src/net/sf/freecol/client/gui/dialog/NativeDemandDialog.java b/src/net/sf/freecol/client/gui/dialog/NativeDemandDialog.java index f2351587f5..483ed9b274 100644 --- a/src/net/sf/freecol/client/gui/dialog/NativeDemandDialog.java +++ b/src/net/sf/freecol/client/gui/dialog/NativeDemandDialog.java @@ -60,7 +60,8 @@ public NativeDemandDialog(FreeColClient freeColClient, JFrame frame, final String nation = Messages.message(unit.getOwner().getNationLabel()); StringTemplate template; - String yes, no; + String yes; + String no; if (type == null) { template = StringTemplate.template("indianDemand.gold.text") .addName("%nation%", nation) diff --git a/src/net/sf/freecol/client/gui/dialog/NegotiationDialog.java b/src/net/sf/freecol/client/gui/dialog/NegotiationDialog.java index 387a428106..791fcf85b4 100644 --- a/src/net/sf/freecol/client/gui/dialog/NegotiationDialog.java +++ b/src/net/sf/freecol/client/gui/dialog/NegotiationDialog.java @@ -82,6 +82,7 @@ import net.sf.freecol.common.model.TradeItem; import net.sf.freecol.common.model.Unit; import net.sf.freecol.common.model.UnitTradeItem; +import java.util.logging.Level; /** @@ -134,34 +135,41 @@ public final class NegotiationDialog extends FreeColPanel { /** The panels for various negotiable data. */ private StanceTradeItemPanel stancePanel; - private GoldTradeItemPanel goldOfferPanel, goldDemandPanel; - private ColonyTradeItemPanel colonyOfferPanel, colonyDemandPanel; - private GoodsTradeItemPanel goodsOfferPanel, goodsDemandPanel; - private InciteTradeItemPanel inciteOfferPanel, inciteDemandPanel; - private UnitTradeItemPanel unitOfferPanel, unitDemandPanel; + private GoldTradeItemPanel goldOfferPanel; + private GoldTradeItemPanel goldDemandPanel; + private ColonyTradeItemPanel colonyOfferPanel; + private ColonyTradeItemPanel colonyDemandPanel; + private GoodsTradeItemPanel goodsOfferPanel; + private GoodsTradeItemPanel goodsDemandPanel; + private InciteTradeItemPanel inciteOfferPanel; + private InciteTradeItemPanel inciteDemandPanel; + private UnitTradeItemPanel unitOfferPanel; + private UnitTradeItemPanel unitDemandPanel; /** A panel showing a summary of the current agreement. */ private JPanel summary; /** Useful internal messages. */ - private StringTemplate demand, offer; + private StringTemplate demand; + private StringTemplate offer; private String exchangeMessage; /** Responses. */ - private FreeColButton send = null, accept = null; + private FreeColButton send = null; + private FreeColButton accept = null; /** * Creates a new {@code NegotiationDialog} instance. * * @param freeColClient The {@code FreeColClient} for the game. - * @param frame The owner frame. * @param our Our {@code FreeColGameObject} that is negotiating. * @param other The other {@code FreeColGameObject}. * @param agreement The {@code DiplomaticTrade} agreement that * is being negotiated. * @param comment An optional {@code StringTemplate} * commentary message. + * @param handler Callback executed when the dialog closes. */ public NegotiationDialog(FreeColClient freeColClient, FreeColGameObject our, FreeColGameObject other, @@ -777,7 +785,7 @@ public void actionPerformed(ActionEvent ae) { .removeTradeItems(ColonyTradeItem.class); break; default: - logger.warning("Bad command: " + command); + if (logger.isLoggable(Level.WARNING)) logger.warning("Bad command: " + command); break; } } @@ -858,7 +866,7 @@ public void actionPerformed(ActionEvent ae) { NegotiationDialog.this.removeTradeItems(GoldTradeItem.class); break; default: - logger.warning("Bad command: " + command); + if (logger.isLoggable(Level.WARNING)) logger.warning("Bad command: " + command); break; } } @@ -986,7 +994,7 @@ public void actionPerformed(ActionEvent ae) { .removeTradeItems(GoodsTradeItem.class); break; default: - logger.warning("Bad command: " + command); + if (logger.isLoggable(Level.WARNING)) logger.warning("Bad command: " + command); break; } } @@ -1106,7 +1114,7 @@ public void actionPerformed(ActionEvent ae) { .removeTradeItems(InciteTradeItem.class); break; default: - logger.warning("Bad command: " + command); + if (logger.isLoggable(Level.WARNING)) logger.warning("Bad command: " + command); break; } } @@ -1227,7 +1235,7 @@ public void actionPerformed(ActionEvent ae) { .removeTradeItems(StanceTradeItem.class); break; default: - logger.warning("Bad command: " + command); + if (logger.isLoggable(Level.WARNING)) logger.warning("Bad command: " + command); break; } } @@ -1348,7 +1356,7 @@ public void actionPerformed(ActionEvent ae) { .removeTradeItems(UnitTradeItem.class); break; default: - logger.warning("Bad command: " + command); + if (logger.isLoggable(Level.WARNING)) logger.warning("Bad command: " + command); break; } } diff --git a/src/net/sf/freecol/client/gui/dialog/OptionsDialog.java b/src/net/sf/freecol/client/gui/dialog/OptionsDialog.java index 6ec89f1e39..283eee1133 100644 --- a/src/net/sf/freecol/client/gui/dialog/OptionsDialog.java +++ b/src/net/sf/freecol/client/gui/dialog/OptionsDialog.java @@ -40,6 +40,7 @@ import net.sf.freecol.common.i18n.Messages; import net.sf.freecol.common.io.FreeColDirectories; import net.sf.freecol.common.option.OptionGroup; +import java.util.logging.Level; /** @@ -156,7 +157,7 @@ private void preparePanel(String headerKey, OptionGroupUI ui) { * Initialize this dialog. * * @param frame The owner frame. - * @param c Extra choices to add beyond the default ok and cancel. + * @param extraButtons Extra choices to add beyond the default ok and cancel. */ protected void initialize(JFrame frame, List extraButtons) { this.panel.add(this.optionPanel, "width 100%, height 100%, gap 0 0, pad 0"); @@ -302,7 +303,7 @@ public void actionPerformed(ActionEvent ae) { } else if (CANCEL.equals(command)) { cancelOptionsDialog(); } else { - logger.warning("Bad event: " + command); + if (logger.isLoggable(Level.WARNING)) logger.warning("Bad event: " + command); } } } diff --git a/src/net/sf/freecol/client/gui/dialog/PreCombatDialog.java b/src/net/sf/freecol/client/gui/dialog/PreCombatDialog.java index 166a68bd19..518686190c 100644 --- a/src/net/sf/freecol/client/gui/dialog/PreCombatDialog.java +++ b/src/net/sf/freecol/client/gui/dialog/PreCombatDialog.java @@ -87,8 +87,8 @@ public PreCombatDialog(FreeColClient freeColClient, JFrame frame, = attacker.getDescription(Unit.UnitLabelType.NATIONAL); JLabel attackerLabel = new UnitLabel(freeColClient, attacker, false, true); - String defenderName = null; - JLabel defenderLabel = null; + String defenderName; + JLabel defenderLabel; if (combatModel.combatIsAttack(attacker, defender)) { Unit defenderUnit = (Unit)defender; defenderName @@ -119,7 +119,7 @@ public PreCombatDialog(FreeColClient freeColClient, JFrame frame, Iterator offenceI = offence.iterator(); Iterator defenceI = defence.iterator(); while (offenceI.hasNext() || defenceI.hasNext()) { - int skip = 0; + int skip; boolean hasOffence = offenceI.hasNext(); if (hasOffence) { JLabel[] labels = ModifierFormat diff --git a/src/net/sf/freecol/client/gui/dialog/SelectDestinationDialog.java b/src/net/sf/freecol/client/gui/dialog/SelectDestinationDialog.java index 8a6c4fe9ca..0c203e7941 100644 --- a/src/net/sf/freecol/client/gui/dialog/SelectDestinationDialog.java +++ b/src/net/sf/freecol/client/gui/dialog/SelectDestinationDialog.java @@ -86,6 +86,7 @@ import net.sf.freecol.common.model.pathfinding.GoalDeciders.MultipleAdjacentDecider; import net.sf.freecol.common.resources.ResourceManager; import net.sf.freecol.common.util.LogBuilder; +import java.util.logging.Level; /** @@ -94,7 +95,6 @@ public final class SelectDestinationDialog extends DeprecatedFreeColDialog implements ListSelectionListener { - @SuppressWarnings("unused") private static final Logger logger = Logger.getLogger(SelectDestinationDialog.class.getName()); @@ -107,6 +107,7 @@ private static class Destination { /** Basic destination comparator, that just uses the name field. */ private static Comparator nameComparator = new Comparator() { + @Override public int compare(Destination d1, Destination d2) { if (!(d1.location instanceof Settlement)) return -1; if (!(d2.location instanceof Settlement)) return 1; @@ -495,7 +496,7 @@ private void loadDestinations(final Unit unit, Settlement s = e.getKey().getTile().getSettlement(); PathNode p = e.getValue(); if (s == null) { - logger.warning("BR#3149 null settlement: " + if (logger.isLoggable(Level.WARNING)) logger.warning("BR#3149 null settlement: " + Messages.message(e.getKey().getLocationLabel()) + " path=" + p.fullPathToString()); return null; diff --git a/src/net/sf/freecol/client/gui/dialog/SelectGoodsAmountDialog.java b/src/net/sf/freecol/client/gui/dialog/SelectGoodsAmountDialog.java index f57fb1915f..fb3c3a53d9 100644 --- a/src/net/sf/freecol/client/gui/dialog/SelectGoodsAmountDialog.java +++ b/src/net/sf/freecol/client/gui/dialog/SelectGoodsAmountDialog.java @@ -61,7 +61,7 @@ public final class SelectGoodsAmountDialog { * * @param freeColClient The enclosing {@code FreeColClient}. * @param goodsType The {@code GoodsType} to select an amount of. - * @param available The amount of goods available. + * @param availableAmount The amount of goods available. * @param defaultAmount The amount to select to start with. * @param pay If true, check the player has sufficient funds. */ diff --git a/src/net/sf/freecol/client/gui/images/DeltaAnimationImageCreator.java b/src/net/sf/freecol/client/gui/images/DeltaAnimationImageCreator.java index 161d54e3c3..f027ed904e 100644 --- a/src/net/sf/freecol/client/gui/images/DeltaAnimationImageCreator.java +++ b/src/net/sf/freecol/client/gui/images/DeltaAnimationImageCreator.java @@ -49,7 +49,7 @@ public BufferedImage getAnimatedScaledRiverDeltaTerrainImage(Direction direction final BufferedImage riverPebblesMaskImage = this.imageCache.getSizedImage(riverPebblesMaskKey, lib.getTileSize(), false); final BufferedImage baseTileMask = lib.getTerrainMask(null); - return generateImage(riverPebblesImage, waterImage, waterVariationNumber, riverWaterMaskImage, riverPebblesMaskImage, baseTileMask); + return generateImage(riverPebblesImage, waterImage, riverWaterMaskImage, riverPebblesMaskImage, baseTileMask); }); return result; @@ -65,8 +65,6 @@ private static ImageResource getRiverPebblesImageResource() { * * @param pebblesImage The pebbles image. That is, the graphics the water is drawn upon. * @param waterImage The water to be drawn. - * @param waterImageVariationNumber The variation number of the - * water image given above. * @param riverWaterMaskImage A mask to be applied to the water image in * order to make the pebbles visible below the water. * @param riverPebblesMaskImage A mask to be applied to the pebbles image in @@ -77,7 +75,6 @@ private static ImageResource getRiverPebblesImageResource() { */ private static BufferedImage generateImage(BufferedImage pebblesImage, BufferedImage waterImage, - int waterImageVariationNumber, BufferedImage riverWaterMaskImage, BufferedImage riverPebblesMaskImage, BufferedImage tileMask) { diff --git a/src/net/sf/freecol/client/gui/images/RiverAnimationImageCreator.java b/src/net/sf/freecol/client/gui/images/RiverAnimationImageCreator.java index bd7cc42823..0cd8551d75 100644 --- a/src/net/sf/freecol/client/gui/images/RiverAnimationImageCreator.java +++ b/src/net/sf/freecol/client/gui/images/RiverAnimationImageCreator.java @@ -64,7 +64,7 @@ public BufferedImage getAnimatedScaledRiverTerrainImage(Tile tile, long ticks) { final BufferedImage maskImage = createRiverMaskImageWithTransitions(baseMaskImage, minorToMajorTransitions); final BufferedImage baseTileMask = lib.getTerrainMask(null); - return generateImage(riverPebblesImage, riverWaterImage, riverVariationNumber, maskImage, baseTileMask); + return generateImage(riverPebblesImage, riverWaterImage, maskImage, baseTileMask); }); return result; @@ -133,8 +133,6 @@ private String directionsToString(List directions) { * * @param pebblesImage The pebbles image. That is, the graphics the water is drawn upon. * @param waterImage The water to be drawn. - * @param riverImageVariationNumber The variation number of the - * water image given above. * @param riverMaskImage A mask to be applied to the water image in * order to make the pebbles visible below the water. In addition, an * enlarged (and less transparent) version of this mask is used for @@ -145,7 +143,6 @@ private String directionsToString(List directions) { */ private static BufferedImage generateImage(BufferedImage pebblesImage, BufferedImage waterImage, - int riverImageVariationNumber, BufferedImage riverMaskImage, BufferedImage tileMask) { final int width = waterImage.getWidth(); diff --git a/src/net/sf/freecol/client/gui/label/CargoLabel.java b/src/net/sf/freecol/client/gui/label/CargoLabel.java index a4a74bbc88..97e955a661 100644 --- a/src/net/sf/freecol/client/gui/label/CargoLabel.java +++ b/src/net/sf/freecol/client/gui/label/CargoLabel.java @@ -28,6 +28,7 @@ * An interface used for updating a {@code CargoPanel} to add or * remove a {@code Component} */ +@FunctionalInterface public interface CargoLabel { /** diff --git a/src/net/sf/freecol/client/gui/label/Draggable.java b/src/net/sf/freecol/client/gui/label/Draggable.java index 5660dcbedb..6b2bb99f73 100644 --- a/src/net/sf/freecol/client/gui/label/Draggable.java +++ b/src/net/sf/freecol/client/gui/label/Draggable.java @@ -20,6 +20,7 @@ package net.sf.freecol.client.gui.label; +@FunctionalInterface public interface Draggable { /** diff --git a/src/net/sf/freecol/client/gui/label/MarketLabel.java b/src/net/sf/freecol/client/gui/label/MarketLabel.java index f8c754b58e..62900c9c31 100644 --- a/src/net/sf/freecol/client/gui/label/MarketLabel.java +++ b/src/net/sf/freecol/client/gui/label/MarketLabel.java @@ -164,11 +164,11 @@ public boolean addCargo(Component comp, Unit carrier, CargoPanel cargoPanel) { int loadable = carrier.getLoadableAmount(label.getType()); if (loadable <= 0) return false; if (loadable > label.getAmount()) loadable = label.getAmount(); - if (cargoPanel.igc().buyGoods(label.getType(), loadable, carrier)) { - cargoPanel.igc().nextModelMessage(); - cargoPanel.update(); - return true; + if (!cargoPanel.igc().buyGoods(label.getType(), loadable, carrier)) { + return false; } - return false; + cargoPanel.igc().nextModelMessage(); + cargoPanel.update(); + return true; } } diff --git a/src/net/sf/freecol/client/gui/label/ProductionLabel.java b/src/net/sf/freecol/client/gui/label/ProductionLabel.java index cbbec6cdbb..46ca895068 100644 --- a/src/net/sf/freecol/client/gui/label/ProductionLabel.java +++ b/src/net/sf/freecol/client/gui/label/ProductionLabel.java @@ -25,11 +25,11 @@ import java.awt.Graphics2D; import java.awt.Image; import java.awt.image.BufferedImage; +import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.ImageIcon; -import net.sf.freecol.FreeCol; import net.sf.freecol.client.ClientOptions; import net.sf.freecol.client.FreeColClient; import net.sf.freecol.client.gui.ImageLibrary; @@ -96,11 +96,12 @@ public ProductionLabel(FreeColClient freeColClient, AbstractGoods ag, super(freeColClient, ag); final ImageLibrary lib = getImageLibrary(); - if (getType() == null) { - FreeCol.trace(logger, "Bad production label (no type)"); - } else if (stockNumber < 0 && getAmount() == 0) { - FreeCol.trace(logger, "Bad production label: " + ag - + " stock=" + stockNumber); + if (getType() == null && logger.isLoggable(Level.WARNING)) { + logger.log(Level.WARNING, "Bad production label (no type)", new Exception()); + } else if (stockNumber < 0 && getAmount() == 0 + && logger.isLoggable(Level.WARNING)) { + logger.log(Level.WARNING, "Bad production label: " + ag + + " stock=" + stockNumber, new Exception()); } final ClientOptions options = freeColClient.getClientOptions(); diff --git a/src/net/sf/freecol/client/gui/label/UnitLabel.java b/src/net/sf/freecol/client/gui/label/UnitLabel.java index 2854e53aaa..17184deda6 100644 --- a/src/net/sf/freecol/client/gui/label/UnitLabel.java +++ b/src/net/sf/freecol/client/gui/label/UnitLabel.java @@ -285,16 +285,15 @@ public void actionPerformed(ActionEvent ae) { if (args.length < 3) break; ColonyTile colonyTile = game.getFreeColGameObject(args[1], ColonyTile.class); - if (args.length >= 4 && "!".equals(args[3])) { - // Claim tile if needed - if (!igc.claimTile(colonyTile.getWorkTile(), - this.unit.getColony())) break; - } + // Claim tile if needed + if (args.length >= 4 && "!".equals(args[3]) + && !igc.claimTile(colonyTile.getWorkTile(), + this.unit.getColony())) break; if (colonyTile != this.unit.getLocation()) { igc.work(this.unit, colonyTile); } - if ((gt = spec.getGoodsType(args[2])) != null - && this.unit.getWorkType() != gt) { + gt = spec.getGoodsType(args[2]); + if (gt != null && this.unit.getWorkType() != gt) { igc.changeWorkType(this.unit, gt); } break; @@ -305,8 +304,8 @@ public void actionPerformed(ActionEvent ae) { if (building != this.unit.getLocation()) { igc.work(this.unit, building); } - if ((gt = spec.getGoodsType(args[2])) != null - && this.unit.getWorkType() != gt) { + gt = spec.getGoodsType(args[2]); + if (gt != null && this.unit.getWorkType() != gt) { igc.changeWorkType(this.unit, gt); } break; diff --git a/src/net/sf/freecol/client/gui/mapviewer/MapAsyncPainter.java b/src/net/sf/freecol/client/gui/mapviewer/MapAsyncPainter.java index 839afd2147..bb836533d6 100644 --- a/src/net/sf/freecol/client/gui/mapviewer/MapAsyncPainter.java +++ b/src/net/sf/freecol/client/gui/mapviewer/MapAsyncPainter.java @@ -64,16 +64,13 @@ public final class MapAsyncPainter { static { if (DEBUG_ASYNC_EVENTS_TO_STDOUT) { - System.out.println(); - System.out.println("Map Async Debug enabled:"); - System.out.println("p\tPrerendering started"); - System.out.println("123\tTime taken prerendering"); - System.out.println("P\tPrerendered image delivered for consumption"); - System.out.println("#\tPrerendered image invalidated and dropped"); - System.out.println(".\tPrerendered image used"); - System.out.println(".\tPrerendered image used"); - System.out.println("!\tNew prerendered image needed immediately"); - System.out.println(); + debugLog("Map Async Debug enabled:"); + debugLog("p\tPrerendering started"); + debugLog("123\tTime taken prerendering"); + debugLog("P\tPrerendered image delivered for consumption"); + debugLog("#\tPrerendered image invalidated and dropped"); + debugLog(".\tPrerendered image used"); + debugLog("!\tNew prerendered image needed immediately"); } } @@ -113,7 +110,10 @@ public BufferedImage getBackBufferImage() { } consumptionLock.wait(); } - } catch (InterruptedException e) {} + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + logger.log(Level.FINE, "Interrupted while waiting for buffer.", e); + } } if (aborted) { @@ -138,7 +138,7 @@ public BufferedImage getBackBufferImage() { lastRenderTimestamp = now; mapViewer.getMapViewerBounds().setFocusMapPoint(newFocus); if (DEBUG_ASYNC_EVENTS_TO_STDOUT) { - System.out.print("."); + debugLog("Prerendered image used"); } consumerIgnoresOldBuffer = false; @@ -146,13 +146,13 @@ public BufferedImage getBackBufferImage() { } if (DEBUG_ASYNC_EVENTS_TO_STDOUT) { - System.out.print("!"); + debugLog("New prerendered image needed immediately"); } if (!used) { - if (DEBUG_ASYNC_EVENTS_TO_STDOUT) { - System.out.println("\n\nWARNING: PRERENDERED IMAGE COMPLETELY UNUSED\nCoordinates: x1=" - + x + ", y1=" + y + ", x2" + (x + origSize.width) + ", y2" + (y + origSize.height) - + " \nOut-of-bounds in buffer: " + size + "\n"); + if (DEBUG_ASYNC_EVENTS_TO_STDOUT && logger.isLoggable(Level.WARNING)) { + logger.warning("PRERENDERED IMAGE COMPLETELY UNUSED\nCoordinates: x1=" + + x + ", y1=" + y + ", x2" + (x + origSize.width) + ", y2" + (y + origSize.height) + + " \nOut-of-bounds in buffer: " + size); } consumerIgnoresOldBuffer = true; } @@ -268,7 +268,7 @@ public void run() { while (!aborted) { try { paint(); - } catch (Exception e) { + } catch (IllegalStateException e) { if (reportedExceptions < MAX_EXCEPTIONS) { logger.log(Level.WARNING, "Unhandled exception while painting.", e); reportedExceptions++; @@ -278,7 +278,10 @@ public void run() { } try { Thread.sleep(MAX_EXCEPTIONS); - } catch (InterruptedException e1) {} + } catch (InterruptedException e1) { + Thread.currentThread().interrupt(); + logger.log(Level.FINE, "Interrupted while throttling exceptions.", e1); + } } } } @@ -290,7 +293,7 @@ private void paint() { } if (DEBUG_ASYNC_EVENTS_TO_STDOUT) { - System.out.print("p"); + debugLog("Prerendering started"); } final long now = System.currentTimeMillis(); @@ -301,14 +304,14 @@ private void paint() { ignoreOldBuffer = false; if (DEBUG_ASYNC_EVENTS_TO_STDOUT) { - System.out.print(" " + (System.currentTimeMillis() - now) + " "); + debugLog("Prerendering time: " + (System.currentTimeMillis() - now) + "ms"); } while (!consumed && !aborted) { if (direction != scrollDirection) { // TODO: Reuse parts of the image. if (DEBUG_ASYNC_EVENTS_TO_STDOUT) { - System.out.print("#"); + debugLog("Prerendered image invalidated and dropped"); } ignoreOldBuffer = true; return; @@ -350,7 +353,7 @@ private void deliverRenderedImage(Point nextMapFocusPointBackBuffer) { mapFocusPointBackBuffer = nextMapFocusPointBackBuffer; if (DEBUG_ASYNC_EVENTS_TO_STDOUT) { - System.out.println("P"); + debugLog("Prerendered image delivered for consumption"); } synchronized (consumptionLock) { @@ -361,4 +364,10 @@ private void deliverRenderedImage(Point nextMapFocusPointBackBuffer) { } } } + + private static void debugLog(String message) { + if (DEBUG_ASYNC_EVENTS_TO_STDOUT && logger.isLoggable(Level.FINER)) { + logger.finer(message); + } + } } diff --git a/src/net/sf/freecol/client/gui/mapviewer/MapViewer.java b/src/net/sf/freecol/client/gui/mapviewer/MapViewer.java index febda79c11..8fc94e6960 100644 --- a/src/net/sf/freecol/client/gui/mapviewer/MapViewer.java +++ b/src/net/sf/freecol/client/gui/mapviewer/MapViewer.java @@ -46,7 +46,6 @@ import java.awt.image.RescaleOp; import java.awt.image.VolatileImage; import java.util.ArrayList; -import java.util.EnumMap; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; @@ -149,7 +148,7 @@ private static enum BorderType { COUNTRY, REGION } * Bounds of the tiles to be rendered. These bounds are scaled according to the * zoom level of the map. */ - private TileBounds tileBounds = new TileBounds(new Dimension(0, 0), 1f); + private TileBounds tileBounds = new TileBounds(new Dimension(0, 0)); private List fullyRepaintedAreas = new ArrayList<>(); @@ -204,7 +203,7 @@ public void changeScale(float newScale) { */ private void updateScaledVariables() { // ATTENTION: we assume that all base tiles have the same size - this.tileBounds = new TileBounds(lib.getTileSize(), lib.getScaleFactor()); + this.tileBounds = new TileBounds(lib.getTileSize()); mapViewerBounds.updateSizeVariables(tileBounds); mapViewerScaledUtils.updateScaledVariables(lib); @@ -216,7 +215,7 @@ private void updateScaledVariables() { * @param size The new map size. */ public void changeSize(Dimension size) { - this.tileBounds = new TileBounds(this.lib.getTileSize(), this.lib.getScaleFactor()); + this.tileBounds = new TileBounds(this.lib.getTileSize()); mapViewerBounds.changeSize(size, this.tileBounds); rpm.markAsDirty(); } @@ -891,7 +890,7 @@ private void displaySettlementLabels(Graphics2D g2d, Settlement settlement, Player player, int colonyLabels, RescaleOp rop) { if (settlement.isDisposed()) { - logger.warning("Settlement display race detected: " + if (logger.isLoggable(Level.WARNING)) logger.warning("Settlement display race detected: " + settlement.getName()); return; } @@ -1410,8 +1409,8 @@ private void displayTerritorialBorders(Graphics2D g2d, Tile tile, (opaque) ? 255 : 100); g2d.setColor(newColor); GeneralPath path = new GeneralPath(GeneralPath.WIND_EVEN_ODD); - final EnumMap borderPoints = mapViewerScaledUtils.getBorderPoints(); - EnumMap controlPoints = mapViewerScaledUtils.getControlPoints(); + final java.util.Map borderPoints = mapViewerScaledUtils.getBorderPoints(); + java.util.Map controlPoints = mapViewerScaledUtils.getControlPoints(); path.moveTo(borderPoints.get(Direction.longSides.get(0)).x, borderPoints.get(Direction.longSides.get(0)).y); @@ -1435,7 +1434,8 @@ private void displayTerritorialBorders(Graphics2D g2d, Tile tile, borderPoints.get(next2).x, borderPoints.get(next2).y); } else { - int dx = 0, dy = 0; + int dx = 0; + int dy = 0; switch(d) { case NW: dx = tileBounds.getHalfWidth(); dy = -tileBounds.getHalfHeight(); break; case NE: dx = tileBounds.getHalfWidth(); dy = tileBounds.getHalfHeight(); break; @@ -1452,7 +1452,8 @@ private void displayTerritorialBorders(Graphics2D g2d, Tile tile, // big corner Direction previous = d.getPreviousDirection(); Direction previous2 = previous.getPreviousDirection(); - int ddx = 0, ddy = 0; + int ddx = 0; + int ddy = 0; switch(d) { case NW: ddy = -tileBounds.getHeight(); break; case NE: ddx = tileBounds.getWidth(); break; @@ -1488,7 +1489,7 @@ private void verifyAndMarkAsClean(Dimension size, final Rectangle clipBounds) { if (relevantDirtyClipBounds.isEmpty() || clipBounds.contains(relevantDirtyClipBounds)) { rpm.markAsClean(); } else { - logger.info("Repaint has been called for a smaller area than what is dirty. " + if (logger.isLoggable(Level.INFO)) logger.info("Repaint has been called for a smaller area than what is dirty. " + "Have you forgotten to call repaint() after marking stuff as dirty? " + "The only known OK instance of this happening is when the GUI is " + "starting up. Bounds: " @@ -1635,7 +1636,8 @@ private void paintEachTile(Graphics2D g2d, Map.Position firstTile, List ti final int x0 = firstTile.getX(); final int y0 = firstTile.getY(); - int xt0 = 0, yt0 = 0; + int xt0 = 0; + int yt0 = 0; for (Tile t : tiles) { final int x = t.getX(); final int y = t.getY(); @@ -1643,7 +1645,8 @@ private void paintEachTile(Graphics2D g2d, Map.Position firstTile, List ti + (y&1) * tileBounds.getHalfWidth(); final int yt = (y-y0) * tileBounds.getHalfHeight(); g2d.translate(xt - xt0, yt - yt0); - xt0 = xt; yt0 = yt; + xt0 = xt; + yt0 = yt; c.render(g2d, t); } @@ -1781,6 +1784,7 @@ public List getSuperExtendedTiles() { /** * A callback for rendering a single tile. */ + @FunctionalInterface private interface TileRenderingCallback { /** diff --git a/src/net/sf/freecol/client/gui/mapviewer/MapViewerBounds.java b/src/net/sf/freecol/client/gui/mapviewer/MapViewerBounds.java index c59e9e8105..4ce5ff6d8c 100644 --- a/src/net/sf/freecol/client/gui/mapviewer/MapViewerBounds.java +++ b/src/net/sf/freecol/client/gui/mapviewer/MapViewerBounds.java @@ -75,7 +75,7 @@ public final class MapViewerBounds { /** * The size of the displayed {@link MapViewer}. */ - private Dimension size = null; + private Dimension size; /** * The current focus Tile as determined by the {@link #mapFocusPoint}. @@ -126,7 +126,7 @@ public final class MapViewerBounds { MapViewerBounds() { this.size = new Dimension(0, 0); // Start empty, update is coming - this.tileBounds = new TileBounds(new Dimension(0, 0), 1f); + this.tileBounds = new TileBounds(new Dimension(0, 0)); } /** @@ -167,10 +167,12 @@ public int setOffsetFocus(Tile tile) { setFocus(tile); positionMap(); - int ret = 0, moveX = -1; + int ret; + int moveX = -1; final Map map = tile.getMap(); - final int tx = tile.getX(), ty = tile.getY(), - width = bottomRightVisibleTile.getX() - topLeftVisibleTile.getX(); + final int tx = tile.getX(); + final int ty = tile.getY(); + final int width = bottomRightVisibleTile.getX() - topLeftVisibleTile.getX(); if (topLeftVisibleTile.getX() <= 0) { // At left edge already if (tx <= width / 4) { ret = -1; @@ -218,8 +220,10 @@ public boolean scrollMap(Direction direction) { return false; } - final int fx = t.getX(), fy = t.getY(); - if ((t = t.getNeighbourOrNull(direction)) == null) { + final int fx = t.getX(); + final int fy = t.getY(); + t = t.getNeighbourOrNull(direction); + if (t == null) { scrollSpeed = 1; return false; } @@ -238,7 +242,8 @@ public boolean scrollMap(Direction direction) { } } - final int tx = t.getX(), ty = t.getY(); + final int tx = t.getX(); + final int ty = t.getY(); int scrollX = mapFocusPoint.x; int scrollY = mapFocusPoint.y; @@ -440,7 +445,8 @@ void positionMap() { * @return The new {@code Point}. */ Point tileToPoint(Tile tile) { - final int tileX = tile.getX(), tileY = tile.getY(); + final int tileX = tile.getX(); + final int tileY = tile.getY(); final int x = topLeftVisibleTilePoint.x + tileBounds.getWidth() * (tileX - topLeftVisibleTile.getX()) + (tileY & 1) * tileBounds.getHalfWidth(); @@ -521,7 +527,8 @@ Tile convertToMapTile(Map map, int x, int y) { // Next, we can calculate the center pixel of the tile-sized // rectangle that was clicked. First, we calculate the // difference in units of rows and columns. - final int fx = this.focus.getX(), fy = this.focus.getY(); + final int fx = this.focus.getX(); + final int fy = this.focus.getY(); int dcol = (x - leftOffset + (x > leftOffset ? tileBounds.getHalfWidth() : -tileBounds.getHalfWidth())) / tileBounds.getWidth(); int drow = (y - topOffset + (y > topOffset ? tileBounds.getHalfHeight() : -tileBounds.getHalfHeight())) diff --git a/src/net/sf/freecol/client/gui/mapviewer/MapViewerRepaintManager.java b/src/net/sf/freecol/client/gui/mapviewer/MapViewerRepaintManager.java index 8b87db93df..c12c9e81ab 100644 --- a/src/net/sf/freecol/client/gui/mapviewer/MapViewerRepaintManager.java +++ b/src/net/sf/freecol/client/gui/mapviewer/MapViewerRepaintManager.java @@ -130,7 +130,8 @@ public boolean isAllDirty() { /** * Marks the given area as dirty for all layers. * - * This method should only be used if {@link paintImmediately} + * This method should only be used if + * {@link javax.swing.JComponent#paintImmediately(int, int, int, int)} * is called both before and after. * * @param bounds The bounds that should be marked dirty. diff --git a/src/net/sf/freecol/client/gui/mapviewer/MapViewerScaledUtils.java b/src/net/sf/freecol/client/gui/mapviewer/MapViewerScaledUtils.java index 240ec4d1f0..53c80a4ff3 100644 --- a/src/net/sf/freecol/client/gui/mapviewer/MapViewerScaledUtils.java +++ b/src/net/sf/freecol/client/gui/mapviewer/MapViewerScaledUtils.java @@ -6,6 +6,7 @@ import java.awt.geom.GeneralPath; import java.awt.geom.Point2D; import java.util.EnumMap; +import java.util.Map; import net.sf.freecol.client.gui.FontLibrary; import net.sf.freecol.client.gui.ImageLibrary; @@ -23,13 +24,16 @@ final class MapViewerScaledUtils { private final GeneralPath fog = new GeneralPath(); /** Fonts (scaled). */ - private Font fontNormal, fontItalic, fontProduction, fontTiny; + private Font fontNormal; + private Font fontItalic; + private Font fontProduction; + private Font fontTiny; /** Points to use to draw the borders. */ - private final EnumMap borderPoints + private final Map borderPoints = new EnumMap<>(Direction.class); /** Support points for quadTo calls when drawing borders. */ - private final EnumMap controlPoints + private final Map controlPoints = new EnumMap<>(Direction.class); /** Stroke to draw the borders with. */ @@ -44,7 +48,7 @@ final class MapViewerScaledUtils { void updateScaledVariables(ImageLibrary lib) { - final TileBounds tileBounds = new TileBounds(lib.getTileSize(), lib.getScaleFactor()); + final TileBounds tileBounds = new TileBounds(lib.getTileSize()); // ATTENTION: we assume that all base tiles have the same size this.fog.reset(); this.fog.moveTo(tileBounds.getHalfWidth(), 0); @@ -127,11 +131,11 @@ Stroke getBorderStroke() { return borderStroke; } - EnumMap getBorderPoints() { + Map getBorderPoints() { return borderPoints; } - EnumMap getControlPoints() { + Map getControlPoints() { return controlPoints; } diff --git a/src/net/sf/freecol/client/gui/mapviewer/MapViewerState.java b/src/net/sf/freecol/client/gui/mapviewer/MapViewerState.java index 0317d1afc8..5f6def5928 100644 --- a/src/net/sf/freecol/client/gui/mapviewer/MapViewerState.java +++ b/src/net/sf/freecol/client/gui/mapviewer/MapViewerState.java @@ -23,7 +23,6 @@ import java.util.List; import net.sf.freecol.client.gui.GUI.ViewMode; -import net.sf.freecol.client.gui.SwingGUI; import net.sf.freecol.common.model.PathNode; import net.sf.freecol.common.model.Tile; import net.sf.freecol.common.model.Unit; @@ -31,7 +30,8 @@ /** * Internal state for the {@link MapViewer}. * - * Methods in this class should only be used by {@link SwingGUI}, + * Methods in this class should only be used by + * {@link net.sf.freecol.client.gui.SwingGUI}, * {@link net.sf.freecol.client.gui.Canvas} or {@link MapViewer}. */ public final class MapViewerState { diff --git a/src/net/sf/freecol/client/gui/mapviewer/RoadPainter.java b/src/net/sf/freecol/client/gui/mapviewer/RoadPainter.java index 0e9246c9c3..e2049ae223 100644 --- a/src/net/sf/freecol/client/gui/mapviewer/RoadPainter.java +++ b/src/net/sf/freecol/client/gui/mapviewer/RoadPainter.java @@ -49,14 +49,17 @@ final class RoadPainter { /** Helper variables for displaying the map. */ - private int tileHeight, tileWidth, halfHeight, halfWidth; + private int tileHeight; + private int tileWidth; + private int halfHeight; + private int halfWidth; - private final EnumMap corners + private final java.util.Map corners = new EnumMap<>(Direction.class); - private final EnumMap> prohibitedRoads + private final java.util.Map> prohibitedRoads = new EnumMap<>(Direction.class); - private Stroke roadStroke = new BasicStroke(2); + private Stroke roadStroke; /** diff --git a/src/net/sf/freecol/client/gui/mapviewer/TileBounds.java b/src/net/sf/freecol/client/gui/mapviewer/TileBounds.java index b4f639d91e..7aef860986 100644 --- a/src/net/sf/freecol/client/gui/mapviewer/TileBounds.java +++ b/src/net/sf/freecol/client/gui/mapviewer/TileBounds.java @@ -28,17 +28,20 @@ public final class TileBounds { /** The height offset to paint a Unit at (in pixels). */ - public static final int UNIT_OFFSET = 20, - OTHER_UNITS_OFFSET_X = -5, // Relative to the state indicator. - OTHER_UNITS_OFFSET_Y = 1, - OTHER_UNITS_WIDTH = 3, - MAX_OTHER_UNITS = 10; + public static final int UNIT_OFFSET = 20; + public static final int OTHER_UNITS_OFFSET_X = -5; // Relative to the state indicator. + public static final int OTHER_UNITS_OFFSET_Y = 1; + public static final int OTHER_UNITS_WIDTH = 3; + public static final int MAX_OTHER_UNITS = 10; /** Tile width and height, and half values thereof. */ - private int tileHeight, tileWidth, halfHeight, halfWidth; + private int tileHeight; + private int tileWidth; + private int halfHeight; + private int halfWidth; - TileBounds(Dimension tileSize, float scaleFactor) { + TileBounds(Dimension tileSize) { this.tileHeight = tileSize.height; this.tileWidth = tileSize.width; this.halfHeight = tileSize.height / 2; diff --git a/src/net/sf/freecol/client/gui/mapviewer/TileViewer.java b/src/net/sf/freecol/client/gui/mapviewer/TileViewer.java index df506d2cae..109c43fb2e 100644 --- a/src/net/sf/freecol/client/gui/mapviewer/TileViewer.java +++ b/src/net/sf/freecol/client/gui/mapviewer/TileViewer.java @@ -58,6 +58,7 @@ import net.sf.freecol.common.model.TileType; import net.sf.freecol.common.model.Unit; import net.sf.freecol.common.util.ImageUtils; +import java.util.logging.Level; /** @@ -84,7 +85,8 @@ public final class TileViewer extends FreeColClientHolder { null); /** The offset to paint the occupation indicator (in pixels). */ - public static final int STATE_OFFSET_X = 25, STATE_OFFSET_Y = 10; + public static final int STATE_OFFSET_X = 25; + public static final int STATE_OFFSET_Y = 10; /** * The image library derived from the parent map viewer. @@ -97,13 +99,16 @@ public final class TileViewer extends FreeColClientHolder { private RoadPainter rp; /** Helper variables for displaying tiles. */ - private int tileHeight, tileWidth, halfHeight; + private int tileHeight; + private int tileWidth; + private int halfHeight; /** Font for tile text. */ private Font tinyFont; /** Fonts for the colony population chip. */ - private Font emphFont, normFont; + private Font emphFont; + private Font normFont; /** @@ -484,6 +489,7 @@ private void drawBaseTileTransitionAtDirection(Graphics2D g2d, Tile tile, Direct } boolean hasRiverDelta(Tile tile) { + boolean found = false; for (Direction direction : Direction.longSides) { Tile borderingTile = tile.getNeighbourOrNull(direction); if (borderingTile == null || tile.isLand() || !borderingTile.isLand() || !tile.isExplored()) { @@ -497,12 +503,11 @@ boolean hasRiverDelta(Tile tile) { final Direction reverseDirection = direction.getReverseDirection(); final int magnitude = river.getRiverConnection(reverseDirection); - if (magnitude <= 0) { - continue; - } - return true; + if (magnitude <= 0) continue; + found = true; + break; } - return false; + return found; } private void drawRiverMouth(Graphics2D g2d, Tile tile, long ticks) { @@ -581,7 +586,7 @@ public void displayOptionalTileText(Graphics2D g2d, Tile tile) { case ClientOptions.DISPLAY_TILE_TEXT_EMPTY: break; default: - logger.warning("displayTileText option " + op + " out of range"); + if (logger.isLoggable(Level.WARNING)) logger.warning("displayTileText option " + op + " out of range"); break; } @@ -686,11 +691,12 @@ public void displaySettlementWithChipsOrPopulationNumber(Graphics2D g2d, } // Draw the alarm chip if needed. - if ((chip = this.lib.getAlarmChip(g2d, is, player)) != null) { + chip = this.lib.getAlarmChip(g2d, is, player); + if (chip != null) { g2d.drawImage(chip, rop, (int)xOffset, (int)yOffset); } } else { - logger.warning("Bogus settlement: " + settlement); + if (logger.isLoggable(Level.WARNING)) logger.warning("Bogus settlement: " + settlement); } } diff --git a/src/net/sf/freecol/client/gui/menu/FreeColMenuBar.java b/src/net/sf/freecol/client/gui/menu/FreeColMenuBar.java index 77cd5f70e6..b204f3bae2 100644 --- a/src/net/sf/freecol/client/gui/menu/FreeColMenuBar.java +++ b/src/net/sf/freecol/client/gui/menu/FreeColMenuBar.java @@ -43,6 +43,7 @@ import net.sf.freecol.client.gui.panel.FreeColImageBorder; import net.sf.freecol.client.gui.panel.Utility; import net.sf.freecol.common.util.ImageUtils; +import java.util.logging.Level; /** @@ -136,7 +137,7 @@ protected JMenuItem getMenuItem(String actionId) { rtn.getInputMap().put(action.getAccelerator(), action.getId()); rtn.getActionMap().put(action.getId(), action); } else { - logger.finest("Could not create menu item. [" + actionId + if (logger.isLoggable(Level.FINEST)) logger.finest("Could not create menu item. [" + actionId + "] not found."); } return rtn; @@ -179,7 +180,7 @@ protected JCheckBoxMenuItem getCheckBoxMenuItem(String actionId) { rtn.getInputMap().put(action.getAccelerator(), action.getId()); rtn.getActionMap().put(action.getId(), action); } else { - logger.finest("Could not create menu item. [" + actionId + "] not found."); + if (logger.isLoggable(Level.FINEST)) logger.finest("Could not create menu item. [" + actionId + "] not found."); } return rtn; @@ -209,7 +210,7 @@ protected JRadioButtonMenuItem getRadioButtonMenuItem(String actionId, rtn.getInputMap().put(action.getAccelerator(), action.getId()); rtn.getActionMap().put(action.getId(), action); } else { - logger.finest("Could not create menu item. [" + actionId + if (logger.isLoggable(Level.FINEST)) logger.finest("Could not create menu item. [" + actionId + "] not found."); } return rtn; diff --git a/src/net/sf/freecol/client/gui/menu/FreeColMenuTest.java b/src/net/sf/freecol/client/gui/menu/FreeColMenuTest.java index 279c60380f..17f19d20b2 100644 --- a/src/net/sf/freecol/client/gui/menu/FreeColMenuTest.java +++ b/src/net/sf/freecol/client/gui/menu/FreeColMenuTest.java @@ -27,6 +27,8 @@ import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; +import java.util.logging.Level; +import java.util.logging.Logger; import javax.swing.ImageIcon; import javax.swing.JFrame; @@ -46,12 +48,14 @@ */ public class FreeColMenuTest implements ActionListener, ItemListener { + private static final Logger logger = Logger.getLogger(FreeColMenuTest.class.getName()); + JTextArea output; JScrollPane scrollPane; final String newline = "\n"; private JMenuBar createMenuBar() { - JMenuBar menuBar = null; + JMenuBar menuBar; FreeColClient client = FreeCol.startTestClient(null); @@ -122,7 +126,7 @@ protected static ImageIcon createImageIcon(String path) { if (imgURL != null) { return new ImageIcon(imgURL); } else { - System.err.println("Couldn't find file: " + path); + if (logger.isLoggable(Level.WARNING)) logger.warning("Couldn't find file: " + path); return null; } } diff --git a/src/net/sf/freecol/client/gui/menu/MenuMouseMotionListener.java b/src/net/sf/freecol/client/gui/menu/MenuMouseMotionListener.java index 2ee551978d..8a5cfd3d27 100644 --- a/src/net/sf/freecol/client/gui/menu/MenuMouseMotionListener.java +++ b/src/net/sf/freecol/client/gui/menu/MenuMouseMotionListener.java @@ -44,7 +44,7 @@ public class MenuMouseMotionListener implements MouseMotionListener { /** * Trivial constructor. * - * @param freeColClient The enclosing {@code FreeColClient}. + * @param scrolling The {@code Scrolling} helper to delegate to. */ public MenuMouseMotionListener(Scrolling scrolling) { this.scrolling = scrolling; diff --git a/src/net/sf/freecol/client/gui/option/ListOptionUI.java b/src/net/sf/freecol/client/gui/option/ListOptionUI.java index 4e2aa8d813..a97797e0c2 100644 --- a/src/net/sf/freecol/client/gui/option/ListOptionUI.java +++ b/src/net/sf/freecol/client/gui/option/ListOptionUI.java @@ -95,7 +95,7 @@ public ListOptionUI(final GUI gui, final ListOption option, AbstractOption c = o.cloneOption(); this.model.addElement(c); } catch (CloneNotSupportedException e) { - logger.log(Level.WARNING, "Can not clone " + o.getId(), e); + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Can not clone " + o.getId(), e); } } this.list = new JList<>(this.model); @@ -148,7 +148,7 @@ public ListOptionUI(final GUI gui, final ListOption option, this.list.repaint(); } } catch (CloneNotSupportedException cnse) { - logger.log(Level.WARNING, "Can not clone: " + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Can not clone: " + option.getTemplate(), cnse); } }); diff --git a/src/net/sf/freecol/client/gui/option/OptionGroupUI.java b/src/net/sf/freecol/client/gui/option/OptionGroupUI.java index f077bee609..a06b4456fc 100644 --- a/src/net/sf/freecol/client/gui/option/OptionGroupUI.java +++ b/src/net/sf/freecol/client/gui/option/OptionGroupUI.java @@ -46,6 +46,7 @@ import net.sf.freecol.common.i18n.Messages; import net.sf.freecol.common.option.Option; import net.sf.freecol.common.option.OptionGroup; +import java.util.logging.Level; /** @@ -88,7 +89,7 @@ public String convertValueToText(Object value, boolean selected, private final List optionUpdaters = new ArrayList<>(); - private final HashMap> optionUIs = new HashMap<>(); + private final Map> optionUIs = new HashMap<>(); private final Map optionGroupSelectionPath = new HashMap<>(); private final JPanel detailPanel; @@ -233,7 +234,7 @@ private void addOptionUI(Option option, boolean editable) { if (ui == null) { ui = OptionUI.getOptionUI(gui, option, editable); if (ui == null) { - logger.warning("Unknown option type: " + option.toString()); + if (logger.isLoggable(Level.WARNING)) logger.warning("Unknown option type: " + option.toString()); return; } if (option.getEnabledBy() != null) { diff --git a/src/net/sf/freecol/client/gui/option/PercentageOptionUI.java b/src/net/sf/freecol/client/gui/option/PercentageOptionUI.java index db90b0acbb..f147ab9ac4 100644 --- a/src/net/sf/freecol/client/gui/option/PercentageOptionUI.java +++ b/src/net/sf/freecol/client/gui/option/PercentageOptionUI.java @@ -19,6 +19,7 @@ package net.sf.freecol.client.gui.option; +import java.util.Dictionary; import java.util.Hashtable; import javax.swing.DefaultBoundedRangeModel; @@ -50,8 +51,7 @@ public PercentageOptionUI(final PercentageOption option, boolean editable) { JSlider slider = getComponent(); slider.setModel(new DefaultBoundedRangeModel(option.getValue(), 0, 0, 100)); - Hashtable labels - = new Hashtable<>(); + Dictionary labels = new Hashtable<>(); labels.put(0, new JLabel("0 %")); labels.put(25, new JLabel("25 %")); labels.put(50, new JLabel("50 %")); diff --git a/src/net/sf/freecol/client/gui/option/RangeOptionUI.java b/src/net/sf/freecol/client/gui/option/RangeOptionUI.java index fea093f506..8639e1233a 100644 --- a/src/net/sf/freecol/client/gui/option/RangeOptionUI.java +++ b/src/net/sf/freecol/client/gui/option/RangeOptionUI.java @@ -19,6 +19,7 @@ package net.sf.freecol.client.gui.option; +import java.util.Dictionary; import java.util.Hashtable; import javax.swing.DefaultBoundedRangeModel; @@ -52,8 +53,7 @@ public RangeOptionUI(final RangeOption option, boolean editable) { slider.setModel(new DefaultBoundedRangeModel(option.getValueRank(), 0, 0, option.getItemValues().size()-1)); - Hashtable labels - = new Hashtable<>(); + Dictionary labels = new Hashtable<>(); int index = 0; for (String string : option.getItemValues().values()) { if (option.localizeLabels()) { diff --git a/src/net/sf/freecol/client/gui/package-info.java b/src/net/sf/freecol/client/gui/package-info.java index 9406207894..f962da59e1 100644 --- a/src/net/sf/freecol/client/gui/package-info.java +++ b/src/net/sf/freecol/client/gui/package-info.java @@ -1,5 +1,5 @@ /** - *

FreeCol Client GUI package

+ *

FreeCol Client GUI package

* *

Contains the graphical user interface (GUI) classes.

* diff --git a/src/net/sf/freecol/client/gui/panel/BuildQueuePanel.java b/src/net/sf/freecol/client/gui/panel/BuildQueuePanel.java index 5deef7766f..a60111a29e 100644 --- a/src/net/sf/freecol/client/gui/panel/BuildQueuePanel.java +++ b/src/net/sf/freecol/client/gui/panel/BuildQueuePanel.java @@ -222,7 +222,7 @@ public boolean importData(JComponent comp, Transferable data) { // What actual panel component was chosen? JList target = BuildQueuePanel.this.convertJComp(comp); if (target == null) { - logger.warning("Build queue import failed to: " + comp); + if (logger.isLoggable(Level.WARNING)) logger.warning("Build queue import failed to: " + comp); return false; } @@ -388,7 +388,7 @@ public int getSourceActions(JComponent comp) { private class BuildQueueMouseAdapter extends MouseAdapter { - private boolean add = true; + private boolean add; private boolean enabled = false; @@ -941,13 +941,14 @@ private void setBuyLabel(BuildableType buildable) { * @return boolean */ private boolean hasBuildingType(BuildingType buildingType) { + BuildingType current = buildingType; while (true) { - if (this.colony.getBuilding(buildingType) == null) { + if (this.colony.getBuilding(current) == null) { return false; - } else if (colony.getBuilding(buildingType).getType() == buildingType) { + } else if (colony.getBuilding(current).getType() == current) { return true; - } else if (buildingType.getUpgradesTo() != null) { - buildingType = buildingType.getUpgradesTo(); + } else if (current.getUpgradesTo() != null) { + current = current.getUpgradesTo(); } else { return false; } diff --git a/src/net/sf/freecol/client/gui/panel/BuildingPanel.java b/src/net/sf/freecol/client/gui/panel/BuildingPanel.java index 9184f1a51f..571e47cf56 100644 --- a/src/net/sf/freecol/client/gui/panel/BuildingPanel.java +++ b/src/net/sf/freecol/client/gui/panel/BuildingPanel.java @@ -48,6 +48,7 @@ import net.sf.freecol.common.model.ProductionInfo; import net.sf.freecol.common.model.Unit; import net.sf.freecol.common.option.GameOptions; +import java.util.logging.Level; /** @@ -238,7 +239,7 @@ public List getUnitLabels() { @Override public void propertyChange(PropertyChangeEvent event) { String property = event.getPropertyName(); - logger.finest(building.getId() + " change " + property + if (logger.isLoggable(Level.FINEST)) logger.finest(building.getId() + " change " + property + ": " + event.getOldValue() + " -> " + event.getNewValue()); update(); diff --git a/src/net/sf/freecol/client/gui/panel/BuildingsLayoutManager.java b/src/net/sf/freecol/client/gui/panel/BuildingsLayoutManager.java index 5c04002df7..80590195f6 100644 --- a/src/net/sf/freecol/client/gui/panel/BuildingsLayoutManager.java +++ b/src/net/sf/freecol/client/gui/panel/BuildingsLayoutManager.java @@ -163,7 +163,7 @@ private void setAllEmptyBuildingSiteVisibility(Container parent, boolean visible private boolean randomizedPlacement(Container parent, Dimension size, boolean dryRun) { final Random r = new Random(layoutSeed); - final List entries = getAllEntries(parent, size); + final List entries = getAllEntries(parent); if (isDefinitelyNotEnoughRoomForLayout(entries, size)) { return false; } @@ -257,7 +257,7 @@ private boolean isDefinitelyNotEnoughRoomForLayout(List entries, Dimensio * * @return The list of children (called entries). */ - private List getAllEntries(Container parent, Dimension size) { + private List getAllEntries(Container parent) { final List entries = new ArrayList<>(parent.getComponentCount()); for (Component c : parent.getComponents()) { if (!c.isVisible()) { diff --git a/src/net/sf/freecol/client/gui/panel/CargoPanel.java b/src/net/sf/freecol/client/gui/panel/CargoPanel.java index 85645751d4..403490dac8 100644 --- a/src/net/sf/freecol/client/gui/panel/CargoPanel.java +++ b/src/net/sf/freecol/client/gui/panel/CargoPanel.java @@ -39,6 +39,7 @@ import net.sf.freecol.common.model.GoodsType; import net.sf.freecol.common.model.StringTemplate; import net.sf.freecol.common.model.Unit; +import java.util.logging.Level; /** * A panel that holds units and goods that represent Units and cargo @@ -230,7 +231,7 @@ public int suggested(GoodsType type) { @Override public void propertyChange(PropertyChangeEvent event) { - logger.finest("CargoPanel change " + event.getPropertyName() + if (logger.isLoggable(Level.FINEST)) logger.finest("CargoPanel change " + event.getPropertyName() + ": " + event.getOldValue() + " -> " + event.getNewValue()); update(); diff --git a/src/net/sf/freecol/client/gui/panel/ChatPanel.java b/src/net/sf/freecol/client/gui/panel/ChatPanel.java index e9400a5f77..6523e829dc 100644 --- a/src/net/sf/freecol/client/gui/panel/ChatPanel.java +++ b/src/net/sf/freecol/client/gui/panel/ChatPanel.java @@ -28,6 +28,7 @@ import javax.swing.JTextField; import net.sf.freecol.client.FreeColClient; +import java.util.logging.Level; /** @@ -106,7 +107,7 @@ public void actionPerformed(ActionEvent ae) { switch (Integer.parseInt(command)) { case CHAT: String message = getChatText(); - if (!message.trim().equals("")) { + if (!message.trim().isEmpty()) { igc().chat(message); } getGUI().removeComponent(this); @@ -115,7 +116,7 @@ public void actionPerformed(ActionEvent ae) { super.actionPerformed(ae); } } catch (NumberFormatException e) { - logger.warning("Invalid ActionEvent, not a number: " + command); + if (logger.isLoggable(Level.WARNING)) logger.warning("Invalid ActionEvent, not a number: " + command); } } } diff --git a/src/net/sf/freecol/client/gui/panel/ColonyPanel.java b/src/net/sf/freecol/client/gui/panel/ColonyPanel.java index 034d6a94d4..8a3d8017cd 100644 --- a/src/net/sf/freecol/client/gui/panel/ColonyPanel.java +++ b/src/net/sf/freecol/client/gui/panel/ColonyPanel.java @@ -131,7 +131,6 @@ * Beware that in debug mode, this might be a server-side version of * the colony which is why we need to call getColony().getSpecification() * to get the spec that corresponds to the good types in this colony. - *

*/ public final class ColonyPanel extends PortPanel implements PropertyChangeListener { @@ -391,6 +390,7 @@ public Dimension getPreferredSize() { * with the layout manager) rather than relying on JScrollPane. */ buildingsScroll.addComponentListener(new ComponentAdapter() { + @Override public void componentResized(ComponentEvent e) { final Dimension preferredSize = buildingsPanel.getLayout().preferredLayoutSize(buildingsPanel); final Dimension viewportSize = buildingsScroll.getViewport().getSize(); @@ -994,7 +994,8 @@ private void updateProduction() { // Check for non-producing locations that can now produce. for (WorkLocation wl : colony.getCurrentWorkLocationsList()) { - boolean change = false, check = wl.getProductionType() == null; + boolean change = false; + boolean check = wl.getProductionType() == null; for (Unit unit : transform(wl.getUnits(), u -> (check || !wl.produces(u.getWorkType())))) { GoodsType workType = wl.getWorkFor(unit); @@ -1057,11 +1058,11 @@ private void generateColonyUnitsMenu() { final Colony colony = getColony(); JPopupMenu colonyUnitsMenu = new JPopupMenu(Messages.message("colonyPanel.colonyUnits")); - ImageIcon unitIcon = null; + ImageIcon unitIcon; final QuickActionMenu unitMenu = new QuickActionMenu(freeColClient, this); Tile colonyTile = colony.getTile(); - JMenuItem subMenu = null; + JMenuItem subMenu; for (final Unit unit : colony.getUnitList()) { WorkLocation wl = unit.getWorkLocation(); @@ -1316,15 +1317,18 @@ public void closeColonyPanel() { if (!getGUI().modalConfirmDialog(null, StringTemplate.key(key), colony, "abandonColony.yes", "abandonColony.no")) return; abandon = true; - } else if ((buildable = colony.getCurrentlyBuilding()) != null) { - int required = buildable.getRequiredPopulation(); - if (required > colony.getUnitCount() - && !getGUI().modalConfirmDialog(null, StringTemplate - .template("colonyPanel.reducePopulation") - .addName("%colony%", colony.getName()) - .addAmount("%number%", required) - .addNamed("%buildable%", buildable), - colony, "ok", "cancel")) return; + } else { + buildable = colony.getCurrentlyBuilding(); + if (buildable != null) { + int required = buildable.getRequiredPopulation(); + if (required > colony.getUnitCount() + && !getGUI().modalConfirmDialog(null, StringTemplate + .template("colonyPanel.reducePopulation") + .addName("%colony%", colony.getName()) + .addAmount("%number%", required) + .addNamed("%buildable%", buildable), + colony, "ok", "cancel")) return; + } } } @@ -1374,7 +1378,7 @@ public void propertyChange(PropertyChangeEvent event) { final Colony colony = getColony(); if (!isShowing() || colony == null) return; String property = event.getPropertyName(); - logger.finest(colony.getName() + " change " + property + if (logger.isLoggable(Level.FINEST)) logger.finest(colony.getName() + " change " + property + ": " + event.getOldValue() + " -> " + event.getNewValue()); @@ -1424,7 +1428,7 @@ public void propertyChange(PropertyChangeEvent event) { // ColonyTiles and Buildings now have their own // propertyChangeListeners so {ColonyTile,Building}.UNIT_CHANGE // events should not arrive here. - logger.warning("Unknown property change event: " + if (logger.isLoggable(Level.WARNING)) logger.warning("Unknown property change event: " + event.getPropertyName()); } } @@ -1612,8 +1616,8 @@ public void update() { try { royalistShield.setIcon(new ImageIcon(lib.getSmallerNationImage(other))); add(royalistShield, "bottom"); - } catch (Exception e) { - logger.log(Level.WARNING, "Shield: " + nation + "/" + other, e); + } catch (IllegalArgumentException e) { + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Shield: " + nation + "/" + other, e); } revalidate(); @@ -1781,7 +1785,7 @@ public Component add(Component comp, boolean editState) { initialize(); return comp; } else { - logger.warning("Invalid component: " + comp); + if (logger.isLoggable(Level.WARNING)) logger.warning("Invalid component: " + comp); return null; } } else { @@ -2014,7 +2018,7 @@ public boolean accepts(Unit unit) { public Component add(Component comp, boolean editState) { if (editState) { if (!(comp instanceof GoodsLabel)) { - logger.warning("Invalid component: " + comp); + if (logger.isLoggable(Level.WARNING)) logger.warning("Invalid component: " + comp); return null; } comp.getParent().remove(comp); @@ -2043,7 +2047,7 @@ public int suggested(GoodsType type) { public void propertyChange(PropertyChangeEvent event) { final Colony colony = getColony(); if (colony != null && event != null) { - logger.finest(colony.getName() + "-warehouse change " + if (logger.isLoggable(Level.FINEST)) logger.finest(colony.getName() + "-warehouse change " + event.getPropertyName() + ": " + event.getOldValue() + " -> " + event.getNewValue()); @@ -2338,6 +2342,7 @@ public final class EmptyBuildingSite extends JPanel{ setOpaque(false); } + @Override protected void paintComponent(Graphics g) { super.paintComponent(g); final ImageLibrary lib = getImageLibrary(); @@ -2412,13 +2417,13 @@ public void initialize() { for (int x = 0; x < tiles.length; x++) { for (int y = 0; y < tiles[x].length; y++) { if (tiles[x][y] == null) { - logger.warning("Null tile for " + getColony() + if (logger.isLoggable(Level.WARNING)) logger.warning("Null tile for " + getColony() + " at " + x + "," + y); continue; } ColonyTile colonyTile = colony.getColonyTile(tiles[x][y]); if (colonyTile == null) { - logger.warning("Null colony tile for " + getColony() + if (logger.isLoggable(Level.WARNING)) logger.warning("Null colony tile for " + getColony() + " on " + tiles[x][y] + " at " + x + "," + y); dump("TILES", colony.getColonyTiles()); continue; @@ -2575,7 +2580,7 @@ private void removePropertyChangeListeners() { public void update() { removeAll(); if (this.colonyTile == null) { - logger.warning("Update of " + getColony() + if (logger.isLoggable(Level.WARNING)) logger.warning("Update of " + getColony() + " null colony tile."); return; } @@ -2654,11 +2659,11 @@ private boolean tryWork(Unit unit) { case NONE: case NATIVES: if (igc().claimTile(tile, colony) && tile.getOwningSettlement() == colony) { - logger.info("Colony " + colony.getName() + if (logger.isLoggable(Level.INFO)) logger.info("Colony " + colony.getName() + " claims tile " + tile + " with unit " + unit.getId()); } else { - logger.warning("Colony " + colony.getName() + if (logger.isLoggable(Level.WARNING)) logger.warning("Colony " + colony.getName() + " did not claim " + tile + " with unit " + unit.getId()); return false; @@ -2747,7 +2752,7 @@ public Component add(Component comp, boolean editState) { @Override public void propertyChange(PropertyChangeEvent event) { String property = event.getPropertyName(); - logger.finest(this.colonyTile.getId() + " change " + property + if (logger.isLoggable(Level.FINEST)) logger.finest(this.colonyTile.getId() + " change " + property + ": " + event.getOldValue() + " -> " + event.getNewValue()); ColonyPanel.this.updateProduction(); diff --git a/src/net/sf/freecol/client/gui/panel/ColorCellEditor.java b/src/net/sf/freecol/client/gui/panel/ColorCellEditor.java index 0591eb2afd..9398ab11b7 100644 --- a/src/net/sf/freecol/client/gui/panel/ColorCellEditor.java +++ b/src/net/sf/freecol/client/gui/panel/ColorCellEditor.java @@ -33,6 +33,7 @@ import net.sf.freecol.client.FreeColClient; import net.sf.freecol.client.gui.GUI; +import java.util.logging.Level; /** @@ -113,7 +114,7 @@ public void actionPerformed(ActionEvent ae) { fireEditingCanceled(); break; default: - logger.warning("Bad event: " + command); + if (logger.isLoggable(Level.WARNING)) logger.warning("Bad event: " + command); break; } } diff --git a/src/net/sf/freecol/client/gui/panel/CornerMapControls.java b/src/net/sf/freecol/client/gui/panel/CornerMapControls.java index 3e84435706..da43e08698 100644 --- a/src/net/sf/freecol/client/gui/panel/CornerMapControls.java +++ b/src/net/sf/freecol/client/gui/panel/CornerMapControls.java @@ -245,20 +245,20 @@ public List getComponentsToAdd(Dimension newSize) { final int totalWidth = buttonsDimension.width + this.miniMapPanel.getWidth() + this.infoPanel.getWidth(); if (totalWidth < newSize.width) { - final Point firstButtonPoint = calculateFirstPosition(newSize, unitButtons, spaceBetweenButtons, buttonsDimension); - layoutUnitButtons(unitButtons, buttonsDimension, firstButtonPoint, spaceBetweenButtons); + final Point firstButtonPoint = calculateFirstPosition(newSize, spaceBetweenButtons, buttonsDimension); + layoutUnitButtons(unitButtons, firstButtonPoint, spaceBetweenButtons); } else { final int numberInTopRow = this.unitButtons.size() / 2; final List bottomRowButtons = unitButtons.subList(numberInTopRow, unitButtons.size()); final Dimension buttonsBottomRowDimension = calculateTotalDimension(bottomRowButtons, spaceBetweenButtons); - final Point firstButtonBottomRowPoint = calculateFirstPosition(newSize, bottomRowButtons, spaceBetweenButtons, buttonsBottomRowDimension); - layoutUnitButtons(bottomRowButtons,buttonsDimension, firstButtonBottomRowPoint, spaceBetweenButtons); + final Point firstButtonBottomRowPoint = calculateFirstPosition(newSize, spaceBetweenButtons, buttonsBottomRowDimension); + layoutUnitButtons(bottomRowButtons, firstButtonBottomRowPoint, spaceBetweenButtons); final List topRowButtons = unitButtons.subList(0, numberInTopRow); final Dimension buttonsTopRowDimension = calculateTotalDimension(topRowButtons, spaceBetweenButtons); - final Point firstButtonTopRowPoint = calculateFirstPosition(newSize, bottomRowButtons, spaceBetweenButtons, buttonsTopRowDimension); - layoutUnitButtons(topRowButtons, buttonsDimension, new Point(firstButtonTopRowPoint.x, firstButtonBottomRowPoint.y - buttonsTopRowDimension.height - spaceBetweenButtons), spaceBetweenButtons); + final Point firstButtonTopRowPoint = calculateFirstPosition(newSize, spaceBetweenButtons, buttonsTopRowDimension); + layoutUnitButtons(topRowButtons, new Point(firstButtonTopRowPoint.x, firstButtonBottomRowPoint.y - buttonsTopRowDimension.height - spaceBetweenButtons), spaceBetweenButtons); } } } @@ -266,7 +266,8 @@ public List getComponentsToAdd(Dimension newSize) { } private static Dimension calculateTotalDimension(List unitButtons, int spaceBetweenButtons) { - int width = -spaceBetweenButtons, height = 0; + int width = -spaceBetweenButtons; + int height = 0; for (UnitButton ub : unitButtons) { if (ub.isShowing()) continue; height = Math.max(height, ub.getHeight()); @@ -275,14 +276,14 @@ private static Dimension calculateTotalDimension(List unitButtons, i return new Dimension(width, height); } - private Point calculateFirstPosition(Dimension newSize, List unitButtons, int spaceBetweenButtons, Dimension buttonsDimension) { + private Point calculateFirstPosition(Dimension newSize, int spaceBetweenButtons, Dimension buttonsDimension) { final int x = this.miniMapPanel.getWidth() + 1 + (this.infoPanel.getX() - this.miniMapPanel.getWidth() - buttonsDimension.width) / 2; final int y = newSize.height - buttonsDimension.height - spaceBetweenButtons; return new Point(x, y); } - private void layoutUnitButtons(List unitButtons, final Dimension buttonsDimension, Point firstButtonPoint, final int spaceBetweenButtons) { + private void layoutUnitButtons(List unitButtons, Point firstButtonPoint, final int spaceBetweenButtons) { int x = firstButtonPoint.x; final int y = firstButtonPoint.y; diff --git a/src/net/sf/freecol/client/gui/panel/DeclarationPanel.java b/src/net/sf/freecol/client/gui/panel/DeclarationPanel.java index f6be39aeef..6eb3dc27f3 100644 --- a/src/net/sf/freecol/client/gui/panel/DeclarationPanel.java +++ b/src/net/sf/freecol/client/gui/panel/DeclarationPanel.java @@ -35,6 +35,7 @@ import java.awt.event.MouseEvent; import java.awt.image.BufferedImage; import java.util.ArrayList; +import java.util.List; import java.util.logging.Logger; import javax.swing.JPanel; @@ -164,7 +165,7 @@ private class SignaturePanel extends JPanel { private final FAFile faFile; - private final ArrayList actionListeners + private final List actionListeners = new ArrayList<>(); private Point[] points = null; @@ -209,7 +210,8 @@ && isTooLarge(join(" ", partNames))) { partNames = newPartNames; } - String first = partNames[0], second = partNames[1]; + String first = partNames[0]; + String second = partNames[1]; String s = join(" ", partNames); if (!isTooLarge(s)) return s; s = first.charAt(0) + ". " + second; @@ -240,13 +242,13 @@ private boolean isTooLarge(String name) { * @param name The name to be used when making the signature. */ public void initialize(String name) { - name = faFile.onlyValidCharacters(name); - name = getAbbreviatedName(name); + String sanitizedName = faFile.onlyValidCharacters(name); + sanitizedName = getAbbreviatedName(sanitizedName); - points = faFile.getPoints(name); + points = faFile.getPoints(sanitizedName); counter = 0; - final Dimension originalSize = faFile.getDimension(name); + final Dimension originalSize = faFile.getDimension(sanitizedName); final Dimension size = getImageLibrary().scale(originalSize); imageBuffer = ImageUtils.createBufferedImage(size.width, size.height); setSize(size); diff --git a/src/net/sf/freecol/client/gui/panel/DefaultTransferHandler.java b/src/net/sf/freecol/client/gui/panel/DefaultTransferHandler.java index 72cd99cfd8..51a03e2491 100644 --- a/src/net/sf/freecol/client/gui/panel/DefaultTransferHandler.java +++ b/src/net/sf/freecol/client/gui/panel/DefaultTransferHandler.java @@ -30,6 +30,7 @@ import java.awt.Toolkit; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.UnsupportedFlavorException; import java.awt.dnd.DragGestureEvent; import java.awt.dnd.DragGestureListener; import java.awt.dnd.DragGestureRecognizer; @@ -39,9 +40,11 @@ import java.awt.dnd.DragSourceDropEvent; import java.awt.dnd.DragSourceEvent; import java.awt.dnd.DragSourceListener; +import java.awt.dnd.InvalidDnDOperationException; import java.awt.event.InputEvent; import java.awt.event.MouseEvent; import java.awt.image.BufferedImage; +import java.io.IOException; import java.util.List; import java.util.logging.Logger; @@ -67,6 +70,7 @@ import net.sf.freecol.common.model.GoodsType; import net.sf.freecol.common.model.Role; import net.sf.freecol.common.model.Unit; +import java.util.logging.Level; /** @@ -139,13 +143,14 @@ private Cursor getCursor(JComponent c) { /** * {@inheritDoc} */ + @Override public void dragGestureRecognized(DragGestureEvent dge) { JComponent c = (JComponent)dge.getComponent(); DefaultTransferHandler th = (DefaultTransferHandler)c.getTransferHandler(); Transferable t = th.createTransferable(c); if (t == null) { - logger.warning("Unable to create transferable for: " + dge); + if (logger.isLoggable(Level.WARNING)) logger.warning("Unable to create transferable for: " + dge); th.exportDone(c, null, NONE); return; } @@ -155,7 +160,7 @@ public void dragGestureRecognized(DragGestureEvent dge) { try { Cursor cursor = getCursor(c); dge.startDrag(cursor, t, this); - } catch (RuntimeException re) { + } catch (InvalidDnDOperationException re) { c.setAutoscrolls(this.scrolls); } } @@ -166,21 +171,25 @@ public void dragGestureRecognized(DragGestureEvent dge) { /** * {@inheritDoc} */ + @Override public void dragEnter(DragSourceDragEvent dsde) {} /** * {@inheritDoc} */ + @Override public void dragOver(DragSourceDragEvent dsde) {} /** * {@inheritDoc} */ + @Override public void dragExit(DragSourceEvent dsde) {} /** * {@inheritDoc} */ + @Override public void dragDropEnd(DragSourceDropEvent dsde) { DragSourceContext dsc = dsde.getDragSourceContext(); JComponent c = (JComponent)dsc.getComponent(); @@ -200,6 +209,7 @@ public void dragDropEnd(DragSourceDropEvent dsde) { /** * {@inheritDoc} */ + @Override public void dropActionChanged(DragSourceDragEvent dsde) { DragSourceContext dsc = dsde.getDragSourceContext(); JComponent comp = (JComponent)dsc.getComponent(); @@ -228,11 +238,13 @@ public void gestured(JComponent c, MouseEvent e, int srcActions, /** * {@inheritDoc} */ + @Override protected void registerListeners() {} /** * {@inheritDoc} */ + @Override protected void unregisterListeners() {} } @@ -332,7 +344,7 @@ private int getAmount(GoodsType goodsType, int available, * @return Always false. */ private boolean importFail(JComponent comp, String data) { - logger.warning("Transfer of " + data + " invalid at: " + comp); + if (logger.isLoggable(Level.WARNING)) logger.warning("Transfer of " + data + " invalid at: " + comp); return false; } @@ -451,14 +463,15 @@ private boolean importGoods(JComponent comp, GoodsLabel label, * @return True if the import succeeds. */ private boolean importMarket(JComponent comp, MarketLabel label) { - if (!(comp instanceof UnitLabel) && !(comp instanceof CargoPanel)) { + JComponent targetComp = comp; + if (!(targetComp instanceof UnitLabel) && !(targetComp instanceof CargoPanel)) { return false; } if (label.isPartialChosen()) { - if (comp instanceof CargoPanel) { + if (targetComp instanceof CargoPanel) { // Verifies that goods can be imported before showing the dialog. - final CargoPanel cargoPanel = (CargoPanel) comp; + final CargoPanel cargoPanel = (CargoPanel) targetComp; if (cargoPanel.getCarrier() == null) { return false; } @@ -471,22 +484,22 @@ private boolean importMarket(JComponent comp, MarketLabel label) { if (amount <= 0) return false; label.setAmount(amount); } - if (comp instanceof UnitLabel) { - if (equipUnitIfPossible((UnitLabel)comp, + if (targetComp instanceof UnitLabel) { + if (equipUnitIfPossible((UnitLabel)targetComp, label.getAbstractGoods())) return true; // Try again with parent - if (comp.getParent() instanceof JComponent) { - comp = (JComponent)comp.getParent(); + if (targetComp.getParent() instanceof JComponent) { + targetComp = (JComponent)targetComp.getParent(); } else { - return importFail(comp, "equipping market goods"); + return importFail(targetComp, "equipping market goods"); } } - if (comp instanceof CargoPanel) { - ((CargoPanel)comp).add(label, true); - comp.revalidate(); + if (targetComp instanceof CargoPanel) { + ((CargoPanel)targetComp).add(label, true); + targetComp.revalidate(); return true; } - return importFail(comp, "market goods"); + return importFail(targetComp, "market goods"); } /** @@ -570,8 +583,9 @@ public int getSourceActions(JComponent comp) { */ @Override public boolean importData(JComponent comp, Transferable t) { + JComponent targetComp = comp; if (!t.isDataFlavorSupported(DefaultTransferHandler.flavor)) { - return importFail(comp, "data flavor"); + return importFail(targetComp, "data flavor"); } boolean ret; @@ -582,15 +596,15 @@ public boolean importData(JComponent comp, Transferable t) { // Get the data to transfer. JLabel data = (JLabel)t.getTransferData(DefaultTransferHandler.flavor); // Do not allow a transferable to be dropped upon itself: - if (comp == data) return false; + if (targetComp == data) return false; // Special cases when dropping onto other labels. - if (comp instanceof AbstractGoodsLabel - || comp instanceof GoodsTypeLabel) { + if (targetComp instanceof AbstractGoodsLabel + || targetComp instanceof GoodsTypeLabel) { // We probably intended to drop on the enclosing parent panel - comp = getDropTarget(comp); - } else if (comp instanceof UnitLabel) { - UnitLabel unitLabel = (UnitLabel)comp; + targetComp = getDropTarget(targetComp); + } else if (targetComp instanceof UnitLabel) { + UnitLabel unitLabel = (UnitLabel)targetComp; /** * 1. If a unit or goods are dropped onto a carrier in port * then the unit/goods is added and the carrier selected. @@ -609,28 +623,30 @@ public boolean importData(JComponent comp, Transferable t) { oldSelectedUnit = portPanel.getSelectedUnitLabel(); } portPanel.setSelectedUnitLabel(unitLabel); - comp = portPanel.getCargoPanel(); + targetComp = portPanel.getCargoPanel(); } else if (data instanceof AbstractGoodsLabel && unitLabel.getUnit().hasAbility(Ability.CAN_BE_EQUIPPED)) { // don't do anything before partial amount has been checked } else { - comp = getDropTarget(comp); + targetComp = getDropTarget(targetComp); } } - ret = (data.getParent() == comp) - ? importFail(comp, "data-already-present") + ret = (data.getParent() == targetComp) + ? importFail(targetComp, "data-already-present") : (data instanceof GoodsTypeLabel) - ? importGoodsType(comp, (GoodsTypeLabel)data) + ? importGoodsType(targetComp, (GoodsTypeLabel)data) : (data instanceof GoodsLabel) - ? importGoods(comp, (GoodsLabel)data, oldSelectedUnit) + ? importGoods(targetComp, (GoodsLabel)data, oldSelectedUnit) : (data instanceof MarketLabel) - ? importMarket(comp, (MarketLabel)data) + ? importMarket(targetComp, (MarketLabel)data) : (data instanceof UnitLabel) - ? importUnit(comp, (UnitLabel)data, oldSelectedUnit) - : importFail(comp, data.toString()); - } catch (Exception e) { // FIXME: Suggest a reconnect? - ret = importFail(comp, "crash: " + e); + ? importUnit(targetComp, (UnitLabel)data, oldSelectedUnit) + : importFail(targetComp, data.toString()); + } catch (UnsupportedFlavorException | IOException e) { + ret = importFail(targetComp, "data flavor"); + } catch (IllegalArgumentException | IllegalStateException e) { // FIXME: Suggest a reconnect? + ret = importFail(targetComp, "crash: " + e); } return ret; } diff --git a/src/net/sf/freecol/client/gui/panel/DragListener.java b/src/net/sf/freecol/client/gui/panel/DragListener.java index 5b96f19844..c6b5d84ee9 100644 --- a/src/net/sf/freecol/client/gui/panel/DragListener.java +++ b/src/net/sf/freecol/client/gui/panel/DragListener.java @@ -23,6 +23,8 @@ import java.awt.Toolkit; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; +import java.util.logging.Level; +import java.util.logging.Logger; import javax.swing.JComponent; import javax.swing.JPopupMenu.Separator; @@ -45,7 +47,9 @@ * be precise). */ public final class DragListener extends MouseAdapter { - + + private static final Logger logger = Logger.getLogger(DragListener.class.getName()); + /** * The maximum numbers of pixels of the user's screen height * before triggering the small flag. @@ -136,9 +140,9 @@ public void mousePressed(MouseEvent e) { if (e.isShiftDown() && e.isAltDown()) { Component[] cArr = comp.getParent().getComponents(); int sum = 0; - for (int i = 0; i < cArr.length; i++) { - if (cArr[i] instanceof AbstractGoodsLabel) { - AbstractGoodsLabel abGoods = (AbstractGoodsLabel) cArr[i]; + for (Component component : cArr) { + if (component instanceof AbstractGoodsLabel) { + AbstractGoodsLabel abGoods = (AbstractGoodsLabel) component; if (abGoods.getAbstractGoods().getType().equals(label.getAbstractGoods().getType())) { sum += abGoods.getAmount(); } @@ -163,9 +167,11 @@ public void mousePressed(MouseEvent e) { ((PortPanel)this.parentPanel).setSelectedUnitLabel(label); } } else if (comp instanceof GoodsTypeLabel) { - ; // Do nothing, TradeRouteInputPanel handles this + if (logger.isLoggable(Level.FINER)) { + logger.finer("Ignoring GoodsTypeLabel drag."); + } } else { - System.err.println("DragListener did not recognize:" + comp); + if (logger.isLoggable(Level.WARNING)) logger.warning("DragListener did not recognize:" + comp); } final TransferHandler handler = comp.getTransferHandler(); diff --git a/src/net/sf/freecol/client/gui/panel/DropListener.java b/src/net/sf/freecol/client/gui/panel/DropListener.java index 570906606e..f1ea687f41 100644 --- a/src/net/sf/freecol/client/gui/panel/DropListener.java +++ b/src/net/sf/freecol/client/gui/panel/DropListener.java @@ -50,12 +50,11 @@ public final class DropListener extends MouseAdapter { public void mouseReleased(MouseEvent e) { Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); Transferable clipData = clipboard.getContents(clipboard); - if (clipData != null) { - if (clipData.isDataFlavorSupported(DefaultTransferHandler.flavor)) { - JComponent comp = (JComponent)e.getSource(); - TransferHandler handler = comp.getTransferHandler(); - handler.importData(comp, clipData); - } + if (clipData != null + && clipData.isDataFlavorSupported(DefaultTransferHandler.flavor)) { + JComponent comp = (JComponent)e.getSource(); + TransferHandler handler = comp.getTransferHandler(); + handler.importData(comp, clipData); } } } diff --git a/src/net/sf/freecol/client/gui/panel/DropTarget.java b/src/net/sf/freecol/client/gui/panel/DropTarget.java index ae8dbd2fb9..f38eaa454a 100644 --- a/src/net/sf/freecol/client/gui/panel/DropTarget.java +++ b/src/net/sf/freecol/client/gui/panel/DropTarget.java @@ -26,6 +26,7 @@ import net.sf.freecol.common.model.Unit; +@FunctionalInterface public interface DropTarget { /** diff --git a/src/net/sf/freecol/client/gui/panel/EuropePanel.java b/src/net/sf/freecol/client/gui/panel/EuropePanel.java index 7438401556..59bd611587 100644 --- a/src/net/sf/freecol/client/gui/panel/EuropePanel.java +++ b/src/net/sf/freecol/client/gui/panel/EuropePanel.java @@ -42,6 +42,7 @@ import javax.swing.KeyStroke; import javax.swing.ScrollPaneConstants; import javax.swing.SwingUtilities; +import javax.swing.text.BadLocationException; import javax.swing.text.SimpleAttributeSet; import javax.swing.text.StyleConstants; import javax.swing.text.StyledDocument; @@ -122,7 +123,7 @@ public void update() { && unit.getDestination().getTile().getMap() == destination); } else { - logger.warning("Bogus DestinationPanel location: " + if (logger.isLoggable(Level.WARNING)) logger.warning("Bogus DestinationPanel location: " + destination + " for unit: " + unit); belongs = false; @@ -177,7 +178,7 @@ public boolean accepts(Unit unit) { public Component add(Component comp, boolean editState) { if (editState) { if (!(comp instanceof UnitLabel)) { - logger.warning("Invalid component: " + comp); + if (logger.isLoggable(Level.WARNING)) logger.warning("Invalid component: " + comp); return null; } final Unit unit = ((UnitLabel)comp).getUnit(); @@ -459,7 +460,7 @@ public boolean accepts(Unit unit) { public Component add(Component comp, boolean editState) { if (editState) { if (!(comp instanceof GoodsLabel)) { - logger.warning("Invalid component: " + comp); + if (logger.isLoggable(Level.WARNING)) logger.warning("Invalid component: " + comp); return null; } @@ -478,7 +479,7 @@ public Component add(Component comp, boolean editState) { igc().unloadCargo(goods, true); break; default: - logger.warning("showBoycottedGoodsDialog fail: " + if (logger.isLoggable(Level.WARNING)) logger.warning("showBoycottedGoodsDialog fail: " + act); break; } @@ -541,10 +542,11 @@ public void cleanup() { private void add(String text) { StyledDocument doc = getStyledDocument(); try { - if (doc.getLength() > 0) text = "\n\n" + text; + String entry = text; + if (doc.getLength() > 0) entry = "\n\n" + entry; - doc.insertString(doc.getLength(), text, null); - } catch (Exception e) { + doc.insertString(doc.getLength(), entry, null); + } catch (BadLocationException e) { logger.log(Level.WARNING, "Transaction log update failure", e); } } @@ -612,8 +614,12 @@ public static enum EuropeAction { private TransactionLog log; - private JButton exitButton, trainButton, purchaseButton, - recruitButton, unloadButton, sailButton; + private JButton exitButton; + private JButton trainButton; + private JButton purchaseButton; + private JButton recruitButton; + private JButton unloadButton; + private JButton sailButton; private final Europe europe; diff --git a/src/net/sf/freecol/client/gui/panel/FindSettlementPanel.java b/src/net/sf/freecol/client/gui/panel/FindSettlementPanel.java index ac23e0f80a..45c03dd88a 100644 --- a/src/net/sf/freecol/client/gui/panel/FindSettlementPanel.java +++ b/src/net/sf/freecol/client/gui/panel/FindSettlementPanel.java @@ -174,7 +174,7 @@ private void updateSearch(DisplayListOption displayListOption) { Object selected = this.settlementList.getSelectedValue(); for (Player player : getGame().getLivePlayerList()) { - boolean ok; + boolean ok = false; switch (displayListOption) { case ONLY_NATIVES: ok = player.isIndian(); @@ -185,9 +185,6 @@ private void updateSearch(DisplayListOption displayListOption) { case ALL: ok = true; break; - default: - ok = false; - break; } if (ok) { for (Settlement s : player.getSettlementList()) { @@ -222,7 +219,6 @@ private void selectSettlement() { public void itemStateChanged(ItemEvent event) { switch (this.displayOptionBox.getSelectedIndex()) { case 0: - default: updateSearch(DisplayListOption.valueOf("ALL")); break; case 1: @@ -230,6 +226,9 @@ public void itemStateChanged(ItemEvent event) { break; case 2: updateSearch(DisplayListOption.valueOf("ONLY_EUROPEAN")); + break; + default: + updateSearch(DisplayListOption.valueOf("ALL")); } } diff --git a/src/net/sf/freecol/client/gui/panel/FreeColPanel.java b/src/net/sf/freecol/client/gui/panel/FreeColPanel.java index 19012ab9cb..2de28f0245 100644 --- a/src/net/sf/freecol/client/gui/panel/FreeColPanel.java +++ b/src/net/sf/freecol/client/gui/panel/FreeColPanel.java @@ -49,6 +49,7 @@ import net.sf.freecol.common.model.Map; import net.sf.freecol.common.model.Player; import net.sf.freecol.common.model.Specification; +import java.util.logging.Level; @@ -329,7 +330,7 @@ public void actionPerformed(ActionEvent ae) { if (OK.equals(command)) { getGUI().removeComponent(this); } else { - logger.warning("Bad event: " + command); + if (logger.isLoggable(Level.WARNING)) logger.warning("Bad event: " + command); } } diff --git a/src/net/sf/freecol/client/gui/panel/FreeColProgressBar.java b/src/net/sf/freecol/client/gui/panel/FreeColProgressBar.java index d209af159b..f2d502d19a 100644 --- a/src/net/sf/freecol/client/gui/panel/FreeColProgressBar.java +++ b/src/net/sf/freecol/client/gui/panel/FreeColProgressBar.java @@ -188,7 +188,7 @@ protected void paintComponent(Graphics g) { g2d.setColor(new Color(0, 0, 0, 70)); g2d.fillRect(getInsets().left, getInsets().top, dvalue, height); } - int dstep = 0; + int dstep; if (max > 0) { dstep = (width * step) / max; if (dstep > 0) { @@ -228,7 +228,7 @@ protected void paintComponent(Graphics g) { int restWidth = getWidth() - stringWidth; int iconWidth = 0; - int iconHeight = 0; + int iconHeight; if (this.image != null) { iconWidth = this.image.getWidth(this); iconHeight = this.image.getHeight(this); diff --git a/src/net/sf/freecol/client/gui/panel/GoodsTypePanel.java b/src/net/sf/freecol/client/gui/panel/GoodsTypePanel.java index 2e6e1fcc26..0a30e511ac 100644 --- a/src/net/sf/freecol/client/gui/panel/GoodsTypePanel.java +++ b/src/net/sf/freecol/client/gui/panel/GoodsTypePanel.java @@ -122,13 +122,11 @@ public boolean addLabel(GoodsTypeLabel label) { */ public boolean removeGoodsType(GoodsType gt) { Component child = findLabel(gt); - if (child != null) { - super.remove(child); - revalidate(); - repaint(); - return true; - } - return false; + if (child == null) return false; + super.remove(child); + revalidate(); + repaint(); + return true; } // Implement DropTarget diff --git a/src/net/sf/freecol/client/gui/panel/InfoPanel.java b/src/net/sf/freecol/client/gui/panel/InfoPanel.java index 11ca498e4c..4fa3ef1c37 100644 --- a/src/net/sf/freecol/client/gui/panel/InfoPanel.java +++ b/src/net/sf/freecol/client/gui/panel/InfoPanel.java @@ -60,6 +60,7 @@ import net.sf.freecol.common.model.Unit; import net.sf.freecol.common.resources.PropertyList; import net.sf.freecol.common.resources.ResourceManager; +import java.util.logging.Level; /** @@ -69,7 +70,6 @@ public final class InfoPanel extends FreeColPanel implements PropertyChangeListener { - @SuppressWarnings("unused") private static final Logger logger = Logger.getLogger(InfoPanel.class.getName()); @@ -487,7 +487,7 @@ public void update() { fillEndPanel(); updated = true; } - logger.info("InfoPanel " + ((updated) ? "updated " : "maintained ") + if (logger.isLoggable(Level.INFO)) logger.info("InfoPanel " + ((updated) ? "updated " : "maintained ") + oldMode + " -> " + this.mode); } } @@ -504,7 +504,7 @@ public void update(MapTransform mapTransform) { this.mapTransform = fillMapPanel(mapTransform); updated = true; } - logger.info("InfoPanel " + ((updated) ? "updated " : "maintained ") + if (logger.isLoggable(Level.INFO)) logger.info("InfoPanel " + ((updated) ? "updated " : "maintained ") + oldMode + " -> " + this.mode + " with " + mapTransform); } @@ -520,7 +520,7 @@ public void update(Tile tile) { this.tile = fillTilePanel(tile); updated = true; } - logger.info("InfoPanel " + ((updated) ? "updated " : "maintained ") + if (logger.isLoggable(Level.INFO)) logger.info("InfoPanel " + ((updated) ? "updated " : "maintained ") + oldMode + " -> " + this.mode + " with tile " + tile); } @@ -536,7 +536,7 @@ public void update(Unit unit) { return; } - boolean updated = false; + boolean updated; InfoPanelMode oldMode = changeMode(InfoPanelMode.UNIT); if (unit != this.unit) { // Only update the PCLs when the unit changes @@ -553,7 +553,7 @@ public void update(Unit unit) { // change, its annotations (such as moves left) might this.unit = fillUnitPanel(unit); updated = true; - logger.info("InfoPanel " + ((updated) ? "updated " : "maintained ") + if (logger.isLoggable(Level.INFO)) logger.info("InfoPanel " + ((updated) ? "updated " : "maintained ") + oldMode + " -> " + this.mode + " with unit " + unit); } diff --git a/src/net/sf/freecol/client/gui/panel/InformationPanel.java b/src/net/sf/freecol/client/gui/panel/InformationPanel.java index 6af1363edf..38188964b4 100644 --- a/src/net/sf/freecol/client/gui/panel/InformationPanel.java +++ b/src/net/sf/freecol/client/gui/panel/InformationPanel.java @@ -64,7 +64,7 @@ public class InformationPanel extends FreeColPanel { /** The skin for this panel. */ - private BufferedImage skin = null; + private BufferedImage skin; /** @@ -77,7 +77,7 @@ public class InformationPanel extends FreeColPanel { * @param images The images to be displayed in the panel. */ public InformationPanel(FreeColClient freeColClient, String[] texts, - FreeColObject[] fcos, ImageIcon[] images) { + FreeColObject[] fcos, ImageIcon... images) { super(freeColClient, null, new MigLayout()); final ImageLibrary fixedImageLibrary = freeColClient.getGUI().getFixedImageLibrary(); diff --git a/src/net/sf/freecol/client/gui/panel/MapControls.java b/src/net/sf/freecol/client/gui/panel/MapControls.java index f0aba643aa..ce3800e25f 100644 --- a/src/net/sf/freecol/client/gui/panel/MapControls.java +++ b/src/net/sf/freecol/client/gui/panel/MapControls.java @@ -55,8 +55,10 @@ public abstract class MapControls extends FreeColClientHolder { protected final MiniMap miniMap; /** Special purpose buttons for the mini map. */ - protected final UnitButton miniMapToggleBorders, - miniMapToggleFogOfWarButton, miniMapZoomOutButton, miniMapZoomInButton; + protected final UnitButton miniMapToggleBorders; + protected final UnitButton miniMapToggleFogOfWarButton; + protected final UnitButton miniMapZoomOutButton; + protected final UnitButton miniMapZoomInButton; /** The buttons to control unit actions. */ protected final List unitButtons = new ArrayList<>(); @@ -67,7 +69,6 @@ public abstract class MapControls extends FreeColClientHolder { * The basic constructor. * * @param freeColClient The {@code FreeColClient} for the game. - * @param useSkin Use a skin or not in the info panel. */ protected MapControls(final FreeColClient freeColClient) { super(freeColClient); diff --git a/src/net/sf/freecol/client/gui/panel/MapEditorToolboxPanel.java b/src/net/sf/freecol/client/gui/panel/MapEditorToolboxPanel.java index 8ae14c634c..c6910f0e03 100644 --- a/src/net/sf/freecol/client/gui/panel/MapEditorToolboxPanel.java +++ b/src/net/sf/freecol/client/gui/panel/MapEditorToolboxPanel.java @@ -112,7 +112,6 @@ private void buildList() { private JToggleButton buildButton(MapEditorTool mapEditorTool, boolean defaultTool) { final String text = Messages.getName(mapEditorTool.getId()); - final MapEditorController ctlr = getFreeColClient().getMapEditorController(); /* TODO: Update description panel? JPanel descriptionPanel = new JPanel(new BorderLayout()); descriptionPanel.add(new JLabel(new ImageIcon(image)), @@ -122,7 +121,6 @@ private JToggleButton buildButton(MapEditorTool mapEditorTool, boolean defaultTo descriptionPanel.setBackground(Color.RED); mt.setDescriptionPanel(descriptionPanel); */ - final Dimension riverSize = ImageLibrary.scaleDimension(getImageLibrary().scale(ImageLibrary.TILE_SIZE), ImageLibrary.SMALLER_SCALE); ImageIcon icon = new ImageIcon(getImageLibrary().getScaledImage("image.ui.includesSpecification")); // TODO: Add icon final JToggleButton button = new JToggleButton(icon); button.setToolTipText(text); diff --git a/src/net/sf/freecol/client/gui/panel/MapEditorTransformPanel.java b/src/net/sf/freecol/client/gui/panel/MapEditorTransformPanel.java index 551a5e4b23..ec5d1bf1e1 100644 --- a/src/net/sf/freecol/client/gui/panel/MapEditorTransformPanel.java +++ b/src/net/sf/freecol/client/gui/panel/MapEditorTransformPanel.java @@ -70,6 +70,7 @@ import net.sf.freecol.common.model.TileType; import net.sf.freecol.common.model.UnitType; import net.sf.freecol.server.model.ServerIndianSettlement; +import java.util.logging.Level; /** @@ -83,7 +84,6 @@ */ public final class MapEditorTransformPanel extends FreeColPanel { - @SuppressWarnings("unused") private static final Logger logger = Logger.getLogger(MapEditorTransformPanel.class.getName()); private static final class RiverTransform extends MapTransform { @@ -236,7 +236,7 @@ public void transform(Tile t) { nativePlayer.addSettlement(sis); sis.placeSettlement(true); sis.addUnits(null); - logger.info("Add settlement " + sis.getName() + " to tile " + t); + if (logger.isLoggable(Level.INFO)) logger.info("Add settlement " + sis.getName() + " to tile " + t); } } @@ -465,7 +465,6 @@ private JToggleButton buildButton(Image image, String text, } if (mt instanceof AssignAreaTransform) { getGUI().showFreeColPanel(chooseAreaModificationPanel, true, null, true); - newMapTransform = null; ctlr.setDisplayAreas(true); } newMapTransform = mt; diff --git a/src/net/sf/freecol/client/gui/panel/MiniMap.java b/src/net/sf/freecol/client/gui/panel/MiniMap.java index 60d25e5f15..08d9ed1d4a 100644 --- a/src/net/sf/freecol/client/gui/panel/MiniMap.java +++ b/src/net/sf/freecol/client/gui/panel/MiniMap.java @@ -156,7 +156,8 @@ private void setFocus(MouseEvent e) { return; } - final int x = e.getX(), y = e.getY(); + final int x = e.getX(); + final int y = e.getY(); final Dimension size = getSize(); final Point focusPoint = getGUI().getFocusMapPoint(); @@ -252,7 +253,7 @@ public void setTileSize(int size) { * * FIXME: Public for MapEditorController.createMiniMapThumbnail. * - * @param graphics The {@code Graphics} context within which to draw. + * @param g2d The {@code Graphics2D} context within which to draw. */ public void paintMap(Graphics2D g2d) { if (getMap() == null) { @@ -315,7 +316,8 @@ public void paintEntireMinimap(Graphics graphics, int tileSize, Dimension size) RenderingHints.VALUE_RENDER_QUALITY); /* Fill the rectangle with background color */ - final int minimapWidth = size.width, minimapHeight = size.height; + final int minimapWidth = size.width; + final int minimapHeight = size.height; g.setColor(ImageLibrary.getMinimapBackgroundColor()); g.fillRect(0, 0, minimapWidth, minimapHeight); @@ -415,7 +417,8 @@ private static void paintEachTile(Graphics2D g2d, Tile firstTile, int tileSize, final int halfWidth = tileSize / 2; final int halfHeight = tileSize / 4; - int xt0 = 0, yt0 = 0; + int xt0 = 0; + int yt0 = 0; for (Tile t : tiles) { final int x = t.getX(); final int y = t.getY(); @@ -423,7 +426,8 @@ private static void paintEachTile(Graphics2D g2d, Tile firstTile, int tileSize, + (y&1) * halfWidth; final int yt = (y-y0) * halfHeight; g2d.translate(xt - xt0, yt - yt0); - xt0 = xt; yt0 = yt; + xt0 = xt; + yt0 = yt; c.render(g2d, t); } @@ -490,6 +494,7 @@ public void paintComponent(Graphics graphics) { /** * A callback for rendering a single tile. */ + @FunctionalInterface private interface TileRenderingCallback { /** diff --git a/src/net/sf/freecol/client/gui/panel/NewPanel.java b/src/net/sf/freecol/client/gui/panel/NewPanel.java index c47ea1ab7f..b7699dca6a 100644 --- a/src/net/sf/freecol/client/gui/panel/NewPanel.java +++ b/src/net/sf/freecol/client/gui/panel/NewPanel.java @@ -54,6 +54,7 @@ import net.sf.freecol.common.model.Specification; import net.sf.freecol.common.model.StringTemplate; import net.sf.freecol.common.option.OptionGroup; +import java.util.logging.Level; /** @@ -248,7 +249,7 @@ public NewPanel(FreeColClient freeColClient, Specification specification) { } if (this.rulesBox.getSelectedItem() == null) { this.rulesBox.setSelectedItem(this.rulesBox.getItemCount()-1); - logger.warning("No TC found for: " + selectRules + if (logger.isLoggable(Level.WARNING)) logger.warning("No TC found for: " + selectRules + ", failling back to " + this.rulesBox.getSelectedItem()); } this.rulesBox @@ -364,7 +365,7 @@ public void actionPerformed(ActionEvent ae) { if (this.difficulty == null) { throw new RuntimeException("No difficulty found for: " + this); } - logger.info("NewPanel initialized with " + this.specification.getId() + if (logger.isLoggable(Level.INFO)) logger.info("NewPanel initialized with " + this.specification.getId() + "/" + this.difficulty.getId()); enableComponents(); setSize(getPreferredSize()); @@ -610,7 +611,7 @@ public void actionPerformed(ActionEvent ae) { super.actionPerformed(ae); break; } - } catch (RuntimeException e) { + } catch (IllegalArgumentException | IllegalStateException e) { gui.showErrorPanel(e, StringTemplate.key("error.unspecified")); } } diff --git a/src/net/sf/freecol/client/gui/panel/PlayersTable.java b/src/net/sf/freecol/client/gui/panel/PlayersTable.java index 5e0df7a1e8..ad0b885231 100644 --- a/src/net/sf/freecol/client/gui/panel/PlayersTable.java +++ b/src/net/sf/freecol/client/gui/panel/PlayersTable.java @@ -290,7 +290,7 @@ private static class HeaderRenderer implements TableCellRenderer { private final Component[] components; public HeaderRenderer(Component... components) { - this.components = components; + this.components = components.clone(); } diff --git a/src/net/sf/freecol/client/gui/panel/QuickActionMenu.java b/src/net/sf/freecol/client/gui/panel/QuickActionMenu.java index 4ae28dd907..05edc8be0a 100644 --- a/src/net/sf/freecol/client/gui/panel/QuickActionMenu.java +++ b/src/net/sf/freecol/client/gui/panel/QuickActionMenu.java @@ -353,11 +353,12 @@ private boolean addWorkItems(final UnitLabel unitLabel) { JMenuItem expertOwned = null; JMenuItem expertUnowned = null; for (GoodsType type : spec.getGoodsTypeList()) { - int bestOwnedProd = bonus + bonusChange, - bestUnownedProd = bonus + bonusChange; - WorkLocation bestOwned = null, bestUnowned = null; + int bestOwnedProd = bonus + bonusChange; + int bestUnownedProd = bonus + bonusChange; + WorkLocation bestOwned = null; + WorkLocation bestUnowned = null; for (WorkLocation wl : colony.getAllWorkLocationsList()) { - int prod = 0; + int prod; switch (wl.getNoAddReason(unit)) { case NONE: prod = wl.getPotentialProduction(type, unitType); @@ -437,7 +438,7 @@ private boolean addEducationItems(final UnitLabel unitLabel) { if (spec.getBoolean(GameOptions.ALLOW_STUDENT_SELECTION)) { for (Unit teacher : transform(unit.getColony().getTeachers(), u -> unit.canBeStudent(u) && u.isInColony())) { - JMenuItem menuItem = null; + JMenuItem menuItem; ImageIcon teacherIcon = new ImageIcon(lib.getSmallerUnitImage(teacher)); if (teacher.getStudent() != unit) { @@ -902,11 +903,9 @@ private void createTileMenu(final ASingleTilePanel singleTilePanel) { private boolean addTileItem(final UnitLabel unitLabel) { final Unit unit = unitLabel.getUnit(); final Tile tile = (unit == null) ? null : unit.getWorkTile(); - if (tile != null) { - addTileItem(tile); - return true; - } - return false; + if (tile == null) return false; + addTileItem(tile); + return true; } /** diff --git a/src/net/sf/freecol/client/gui/panel/RecruitPanel.java b/src/net/sf/freecol/client/gui/panel/RecruitPanel.java index 49aa451694..49cf351366 100644 --- a/src/net/sf/freecol/client/gui/panel/RecruitPanel.java +++ b/src/net/sf/freecol/client/gui/panel/RecruitPanel.java @@ -21,6 +21,7 @@ import java.awt.event.ActionEvent; import java.util.List; +import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.AbstractAction; @@ -142,8 +143,10 @@ public void actionPerformed(ActionEvent ae) { if (!shouldEnable) getGUI().removeComponent(this); return; } - } catch (NumberFormatException e) {} - logger.warning("Invalid action command: " + command); + } catch (NumberFormatException e) { + if (logger.isLoggable(Level.FINE)) logger.log(Level.FINE, "Invalid recruit command: " + command, e); + } + if (logger.isLoggable(Level.WARNING)) logger.warning("Invalid action command: " + command); } } diff --git a/src/net/sf/freecol/client/gui/panel/StartGamePanel.java b/src/net/sf/freecol/client/gui/panel/StartGamePanel.java index c0aa0040ac..18e7da3a60 100644 --- a/src/net/sf/freecol/client/gui/panel/StartGamePanel.java +++ b/src/net/sf/freecol/client/gui/panel/StartGamePanel.java @@ -62,7 +62,10 @@ public final class StartGamePanel extends FreeColPanel { private JTextArea chatArea; - private JButton start, cancel, gameOptions, mapGeneratorOptions; + private JButton start; + private JButton cancel; + private JButton gameOptions; + private JButton mapGeneratorOptions; private PlayersTable table; @@ -144,7 +147,8 @@ public void initialize(boolean singlePlayer) { NationOptions nationOptions = getGame().getNationOptions(); cancel = Utility.localizedButton("cancel"); - JScrollPane chatScroll = null, tableScroll; + JScrollPane chatScroll = null; + JScrollPane tableScroll; table = new PlayersTable(getFreeColClient(), nationOptions, getMyPlayer()); diff --git a/src/net/sf/freecol/client/gui/panel/StatisticsPanel.java b/src/net/sf/freecol/client/gui/panel/StatisticsPanel.java index a4023cb15f..eea946639a 100644 --- a/src/net/sf/freecol/client/gui/panel/StatisticsPanel.java +++ b/src/net/sf/freecol/client/gui/panel/StatisticsPanel.java @@ -58,7 +58,8 @@ public final class StatisticsPanel extends FreeColPanel { private static class StatisticsModel extends AbstractTableModel { - private static final int NAME_COLUMN = 0, VALUE_COLUMN = 1; + private static final int NAME_COLUMN = 0; + private static final int VALUE_COLUMN = 1; private final String[] columnNames = { "name", "value" }; private Object[][] data = null; @@ -144,6 +145,8 @@ && row < getRowCount() && column < getColumnCount()) { return data[NAME_COLUMN][row]; case StatisticsModel.VALUE_COLUMN: return data[VALUE_COLUMN][row]; + default: + break; } } return null; diff --git a/src/net/sf/freecol/client/gui/panel/TradeRouteInputPanel.java b/src/net/sf/freecol/client/gui/panel/TradeRouteInputPanel.java index 5bb51801fa..b52c4786b1 100644 --- a/src/net/sf/freecol/client/gui/panel/TradeRouteInputPanel.java +++ b/src/net/sf/freecol/client/gui/panel/TradeRouteInputPanel.java @@ -325,7 +325,7 @@ public boolean importData(JComponent target, Transferable data) { } catch (UnsupportedFlavorException e) { logger.log(Level.WARNING, "Drag&drop failed.", e); return false; - } catch (RuntimeException e) { + } catch (IllegalStateException e) { logger.log(Level.WARNING, "Drag&drop failed.", e); throw e; } @@ -630,7 +630,7 @@ private void enableImport(GoodsType gt) { /** * Cancel import of goods at the selected stops. * - * @param gt The {@code GoodsType} to stop importing. + * @param gtl The {@code GoodsTypeLabel} to stop importing. */ private void cancelImport(GoodsTypeLabel gtl) { this.stopGoodsTypesPanel.remove(gtl); @@ -657,8 +657,8 @@ private void cancelImport(GoodsTypeLabel gtl) { * Add any stops selected in the destination selector. */ private void addSelectedStops() { - int startIndex = -1; - int endIndex = -1; + int startIndex; + int endIndex; int sel = this.destinationSelector.getSelectedIndex(); if (sel == 0) { // All colonies + Europe startIndex = 1; diff --git a/src/net/sf/freecol/client/gui/panel/TradeRoutePanel.java b/src/net/sf/freecol/client/gui/panel/TradeRoutePanel.java index c82f8976f7..895b6ecff4 100644 --- a/src/net/sf/freecol/client/gui/panel/TradeRoutePanel.java +++ b/src/net/sf/freecol/client/gui/panel/TradeRoutePanel.java @@ -46,6 +46,7 @@ import net.sf.freecol.common.model.StringTemplate; import net.sf.freecol.common.model.TradeRoute; import net.sf.freecol.common.model.Unit; +import java.util.logging.Level; /** @@ -53,7 +54,6 @@ */ public final class TradeRoutePanel extends FreeColPanel { - @SuppressWarnings("unused") private static final Logger logger = Logger.getLogger(TradeRoutePanel.class.getName()); /** Compare trade routes by name. */ @@ -135,15 +135,20 @@ public Component getListCellRendererComponent(JList list, final String name = selected.getName(); getGUI().showTradeRouteInputPanel(selected) .addClosingCallback(() -> { - StringTemplate template = null; + StringTemplate template; if (selected.getName() == null) { // Cancelled selected.setName(name); - } else if ((template = selected.verify()) == null - && (template = selected.verifyUniqueName()) == null) { - igc().updateTradeRoute(selected); - updateList(selected); } else { - getGUI().showInformationPanel(template); + template = selected.verify(); + if (template == null) { + template = selected.verifyUniqueName(); + } + if (template == null) { + igc().updateTradeRoute(selected); + updateList(selected); + } else { + getGUI().showInformationPanel(template); + } } }); }); @@ -228,19 +233,24 @@ private void newRoute() { final TradeRoute newRoute = igc().newTradeRoute(player); getGUI().showTradeRouteInputPanel(newRoute) .addClosingCallback(() -> { - StringTemplate template = null; + StringTemplate template; String name = newRoute.getName(); if (name == null) { // Cancelled igc().deleteTradeRoute(newRoute); updateList(null); - } else if ((template = newRoute.verify()) != null - && (template = newRoute.verifyUniqueName()) != null) { - updateList(null); - getGUI().showInformationPanel(template); } else { - igc().updateTradeRoute(newRoute); - if (u != null) igc().assignTradeRoute(u, newRoute); - updateList(newRoute); + template = newRoute.verify(); + if (template != null) { + template = newRoute.verifyUniqueName(); + } + if (template != null) { + updateList(null); + getGUI().showInformationPanel(template); + } else { + igc().updateTradeRoute(newRoute); + if (u != null) igc().assignTradeRoute(u, newRoute); + updateList(newRoute); + } } }); } @@ -279,7 +289,7 @@ private void updateList(TradeRoute selectRoute) { routes.add(tr); } else { igc().deleteTradeRoute(tr); - logger.warning("Dropped trade route: " + Messages.message(st)); + if (logger.isLoggable(Level.WARNING)) logger.warning("Dropped trade route: " + Messages.message(st)); } } routes.sort(tradeRouteComparator); diff --git a/src/net/sf/freecol/client/gui/panel/UnitButton.java b/src/net/sf/freecol/client/gui/panel/UnitButton.java index 44ace7b01f..3cefaddd53 100644 --- a/src/net/sf/freecol/client/gui/panel/UnitButton.java +++ b/src/net/sf/freecol/client/gui/panel/UnitButton.java @@ -31,6 +31,7 @@ import net.sf.freecol.client.gui.action.ActionManager; import net.sf.freecol.client.gui.action.FreeColAction; +import java.util.logging.Level; /** @@ -94,7 +95,7 @@ protected void configurePropertiesFromAction(Action a) { setPreferredSize(new Dimension(bi.getIconWidth(), bi.getIconHeight())); setMinimumSize(new Dimension(bi.getIconWidth(), bi.getIconHeight())); } else { - logger.warning("Action " + a + " has no BUTTON_IMAGE"); + if (logger.isLoggable(Level.WARNING)) logger.warning("Action " + a + " has no BUTTON_IMAGE"); } } } diff --git a/src/net/sf/freecol/client/gui/panel/UnitPanel.java b/src/net/sf/freecol/client/gui/panel/UnitPanel.java index 95bcaee04b..dff3f021a7 100644 --- a/src/net/sf/freecol/client/gui/panel/UnitPanel.java +++ b/src/net/sf/freecol/client/gui/panel/UnitPanel.java @@ -33,6 +33,7 @@ import net.sf.freecol.common.model.TradeRoute; import net.sf.freecol.common.model.Unit; import net.sf.freecol.server.ai.AIUnit; +import java.util.logging.Level; /** @@ -203,7 +204,7 @@ protected boolean setSelectedUnit(Unit unit) { */ @Override public void propertyChange(PropertyChangeEvent event) { - logger.finest(getName() + " change " + event.getPropertyName() + if (logger.isLoggable(Level.FINEST)) logger.finest(getName() + " change " + event.getPropertyName() + ": " + event.getOldValue() + " -> " + event.getNewValue()); update(); diff --git a/src/net/sf/freecol/client/gui/panel/WorkProductionPanel.java b/src/net/sf/freecol/client/gui/panel/WorkProductionPanel.java index 4a9f952847..d821cc7c7b 100644 --- a/src/net/sf/freecol/client/gui/panel/WorkProductionPanel.java +++ b/src/net/sf/freecol/client/gui/panel/WorkProductionPanel.java @@ -74,9 +74,9 @@ public WorkProductionPanel(FreeColClient freeColClient, Unit unit) { final WorkLocation wl = (WorkLocation)unit.getLocation(); final GoodsType workType = unit.getWorkType(); - String shortName = ""; - String longName = ""; - Image image = null; + String shortName; + String longName; + Image image; float result = wl.getBaseProduction(wl.getProductionType(), workType, unitType); diff --git a/src/net/sf/freecol/client/gui/panel/WrapLayout.java b/src/net/sf/freecol/client/gui/panel/WrapLayout.java index 34669d1962..20dc71b7c8 100644 --- a/src/net/sf/freecol/client/gui/panel/WrapLayout.java +++ b/src/net/sf/freecol/client/gui/panel/WrapLayout.java @@ -110,7 +110,7 @@ public enum HorizontalGap { * * @see #withHorizontalAlignment(HorizontalAlignment) * @see #withLayoutStyle(LayoutStyle) - * @see #withHorizontalGap(HorizontalGap, int) + * @see #withHorizontalGap(HorizontalGap, int, int) */ public WrapLayout() { @@ -241,7 +241,7 @@ private Dimension layoutSize(Container target, boolean preferred) { } private Layout determineLayout(Container target, boolean preferred) { - int targetWidth = target.getSize().width; + int targetWidth; Container container = target; while (container.getSize().width == 0 && container.getParent() != null) { container = container.getParent(); @@ -395,7 +395,7 @@ public void layoutContainer(Container parent) { if (layout.dimension.width > size.width || layout.dimension.height > size.height) { layout = determineLayout(parent, size.width, false); } - applyLayout(parent, size, layout); + applyLayout(size, layout); } } @@ -407,11 +407,11 @@ public void layoutContainer(Container parent, boolean preferred) { synchronized (parent.getTreeLock()) { final Dimension size = parent.getSize(); final Layout layout = determineLayout(parent, size.width, preferred); - applyLayout(parent, size, layout); + applyLayout(size, layout); } } - private void applyLayout(Container parent, Dimension size, Layout layout) { + private void applyLayout(Dimension size, Layout layout) { final Point offsetAll = determineOffsetForCentering(size, layout.dimension); final int rowsSize = layout.rows.size(); @@ -525,4 +525,4 @@ public Child(Component component, Rectangle bounds) { this.bounds = bounds; } } -} \ No newline at end of file +} diff --git a/src/net/sf/freecol/client/gui/panel/colopedia/BuildingDetailPanel.java b/src/net/sf/freecol/client/gui/panel/colopedia/BuildingDetailPanel.java index 27d71e0d15..62a5f0039a 100644 --- a/src/net/sf/freecol/client/gui/panel/colopedia/BuildingDetailPanel.java +++ b/src/net/sf/freecol/client/gui/panel/colopedia/BuildingDetailPanel.java @@ -31,6 +31,8 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; import java.util.Map; import javax.swing.ImageIcon; @@ -65,6 +67,8 @@ public class BuildingDetailPanel extends ColopediaGameObjectTypePanel { + private static final Logger logger = Logger.getLogger(BuildingDetailPanel.class.getName()); + /** * Creates a new instance of this ColopediaDetailPanel. * @@ -172,7 +176,7 @@ public void buildDetail(String id, JPanel panel) { panel.add(Utility.localizedLabel("colopedia.buildings.requires"), "top"); panel.add(textPane, "span, growx"); } catch (BadLocationException e) { - //logger.warning(e.toString()); + logger.log(Level.FINE, "Failed to build building detail text.", e); } // Costs to build - Hammers & Tools diff --git a/src/net/sf/freecol/client/gui/panel/colopedia/ColopediaGameObjectTypePanel.java b/src/net/sf/freecol/client/gui/panel/colopedia/ColopediaGameObjectTypePanel.java index f2fee7372c..6165a01e6f 100644 --- a/src/net/sf/freecol/client/gui/panel/colopedia/ColopediaGameObjectTypePanel.java +++ b/src/net/sf/freecol/client/gui/panel/colopedia/ColopediaGameObjectTypePanel.java @@ -212,7 +212,7 @@ public JComponent getModifierComponent(Modifier modifier) { .getGoodsType(modifier.getId()); String bonus = ModifierFormat.getModifierAsString(modifier); return getGoodsButton(goodsType, bonus); - } catch (Exception e) { + } catch (IllegalArgumentException e) { // not a production bonus JLabel label = new JLabel(ModifierFormat.getFeatureAsString(modifier) + ": " + ModifierFormat.getModifierAsString(modifier)); diff --git a/src/net/sf/freecol/client/gui/panel/colopedia/ColopediaPanel.java b/src/net/sf/freecol/client/gui/panel/colopedia/ColopediaPanel.java index cf6626a495..8d11d59d70 100644 --- a/src/net/sf/freecol/client/gui/panel/colopedia/ColopediaPanel.java +++ b/src/net/sf/freecol/client/gui/panel/colopedia/ColopediaPanel.java @@ -47,6 +47,7 @@ import net.sf.freecol.client.gui.panel.Utility; import net.sf.freecol.common.i18n.Messages; import net.sf.freecol.common.model.FreeColObject; +import java.util.logging.Level; /** @@ -214,7 +215,7 @@ private void showDetails(ColopediaTreeItem nodeItem) { private void select(String id) { DefaultMutableTreeNode node = nodeMap.get(id); if (node == null) { - logger.warning("Unable to find node with id '" + id + "'."); + if (logger.isLoggable(Level.WARNING)) logger.warning("Unable to find node with id '" + id + "'."); } else { TreePath oldPath = tree.getSelectionPath(); if (oldPath != null && oldPath.getParentPath() != null) { diff --git a/src/net/sf/freecol/client/gui/panel/colopedia/FatherDetailPanel.java b/src/net/sf/freecol/client/gui/panel/colopedia/FatherDetailPanel.java index f219a44b90..62689e83f9 100644 --- a/src/net/sf/freecol/client/gui/panel/colopedia/FatherDetailPanel.java +++ b/src/net/sf/freecol/client/gui/panel/colopedia/FatherDetailPanel.java @@ -43,6 +43,7 @@ import net.sf.freecol.common.model.StringTemplate; import net.sf.freecol.common.model.Turn; import net.sf.freecol.common.util.ImageUtils; +import java.util.logging.Level; /** @@ -107,7 +108,7 @@ public void addSubTrees(DefaultMutableTreeNode root) { public void buildDetail(String id, JPanel panel) { FoundingFather father = getSpecification().getFoundingFather(id); if (father == null) { - logger.warning("Bogus father detail requested for: " + id); + if (logger.isLoggable(Level.WARNING)) logger.warning("Bogus father detail requested for: " + id); } else { buildDetail(father, panel); } diff --git a/src/net/sf/freecol/client/gui/panel/colopedia/GoodsDetailPanel.java b/src/net/sf/freecol/client/gui/panel/colopedia/GoodsDetailPanel.java index 60efb292f3..0cf06f9c23 100644 --- a/src/net/sf/freecol/client/gui/panel/colopedia/GoodsDetailPanel.java +++ b/src/net/sf/freecol/client/gui/panel/colopedia/GoodsDetailPanel.java @@ -156,8 +156,7 @@ public void buildDetail(String id, JPanel panel) { } } List roles = new ArrayList<>(); - allTypes = filterBuildables(getSpecification().getRolesList(), - roles, type); + filterBuildables(getSpecification().getRolesList(), roles, type); if (!roles.isEmpty()) { panel.add(Utility.localizedLabel("colopedia.goods.equipment"), "newline 20"); diff --git a/src/net/sf/freecol/client/gui/panel/report/CompactLabourReport.java b/src/net/sf/freecol/client/gui/panel/report/CompactLabourReport.java index 95033450c9..24182f5a87 100644 --- a/src/net/sf/freecol/client/gui/panel/report/CompactLabourReport.java +++ b/src/net/sf/freecol/client/gui/panel/report/CompactLabourReport.java @@ -253,6 +253,7 @@ private void addHeader() { */ private int addLocationData(LabourData.LocationData data, Colony colony, int row) { + int currentRow = row; boolean allColonists = data.getUnitData().isSummary(); LabourData.UnitData unit = data.getUnitData(); @@ -271,9 +272,9 @@ private int addLocationData(LabourData.LocationData data, Colony colony, } } } - addLocationSummary(data, row); + addLocationSummary(data, currentRow); - int buildingStartRow = row; + int buildingStartRow = currentRow; //details int otherAmateurs = data.getOtherWorkingAmateurs().getColonists(); @@ -283,75 +284,75 @@ private int addLocationData(LabourData.LocationData data, Colony colony, workingAs, createNonCountedLabel(otherAmateurs), data.getOtherWorkingAmateurs().getProduction(), - row); - row++; + currentRow); + currentRow++; } - row = addRow(data, + currentRow = addRow(data, unitName, allColonists ? Messages.message("report.labour.expertsWorking") : workingAs, data.getWorkingProfessionals().getColonists(), data.getWorkingProfessionals().getProduction(), - row); + currentRow); - int notProducingStartRow = row; + int notProducingStartRow = currentRow; if (showBuildings) { - if (productionWL != null && row > buildingStartRow) { + if (productionWL != null && currentRow > buildingStartRow) { JLabel buildingLabel = Utility.localizedLabel(productionWL.getLabel()); buildingLabel.setBorder(Utility.getCellBorder()); - reportPanel.add(buildingLabel, "cell " + BUILDING_COLUMN + " " + buildingStartRow + " 1 " + (row - buildingStartRow)); - buildingStartRow = row; + reportPanel.add(buildingLabel, "cell " + BUILDING_COLUMN + " " + buildingStartRow + " 1 " + (currentRow - buildingStartRow)); + buildingStartRow = currentRow; } else { - reportPanel.add(createEmptyLabel(), "cell " + BUILDING_COLUMN + " " + buildingStartRow + " 1 " + (row - buildingStartRow)); + reportPanel.add(createEmptyLabel(), "cell " + BUILDING_COLUMN + " " + buildingStartRow + " 1 " + (currentRow - buildingStartRow)); } } - row = addRow(data, + currentRow = addRow(data, unitName, Messages.message(allColonists ? "report.labour.amateursWorking" : "report.labour.workingAsOther"), data.getWorkingAmateurs(), - 0, row); + 0, currentRow); if (data.getNotWorking() > 0) { addRow(data, unitName, Messages.message("report.labour.notWorking"), createNumberLabel(data.getNotWorking(), "report.labour.notWorking.tooltip"), - 0, row); - row++; + 0, currentRow); + currentRow++; } WorkLocation school = (colony != null && data.isTraining()) ? colony.getWorkLocationWithAbility(Ability.TEACH) : null; - if (showBuildings && school != null && row > buildingStartRow) { + if (showBuildings && school != null && currentRow > buildingStartRow) { reportPanel.add(createEmptyLabel(), "cell " + BUILDING_COLUMN - + " " + buildingStartRow + " 1 " + (row - buildingStartRow)); - buildingStartRow = row; + + " " + buildingStartRow + " 1 " + (currentRow - buildingStartRow)); + buildingStartRow = currentRow; } - row = addRow(data, + currentRow = addRow(data, unitName, Messages.message("report.labour.teacher"), data.getTeachers(), - 0, row); + 0, currentRow); if (!allColonists) { - row = addRow(data, + currentRow = addRow(data, data.getOtherStudentsName(), Messages.message(StringTemplate .template("report.labour.learning") .addName("%unit%", data.getUnitData().getUnitName())), data.getOtherStudents(), - 0, row); + 0, currentRow); } int studentCount = data.getStudents(); if (studentCount > 0) { if (allColonists) { - addRow(data, null, Messages.message("report.labour.sutdent"), createNonCountedLabel(studentCount), 0, row); + addRow(data, null, Messages.message("report.labour.sutdent"), createNonCountedLabel(studentCount), 0, currentRow); } else { final Predicate teachingPred = u -> { final Unit student = u.getStudent(); @@ -372,27 +373,27 @@ private int addLocationData(LabourData.LocationData data, Colony colony, data.getUnitData().getUnitName(), student, createNumberLabel(-studentCount, "report.labour.subtracted.tooltip"), - 0, row); + 0, currentRow); } - row++; + currentRow++; } - if (showBuildings && row > buildingStartRow) { + if (showBuildings && currentRow > buildingStartRow) { JLabel buildingLabel = new JLabel((school == null) ? "" : Messages.message(school.getLabel())); buildingLabel.setBorder(Utility.getCellBorder()); reportPanel.add(buildingLabel, "cell " + BUILDING_COLUMN + " " + buildingStartRow - + " 1 " + (row - buildingStartRow)); + + " 1 " + (currentRow - buildingStartRow)); } - if (row > notProducingStartRow && data.getUnitData().showProduction()) { + if (currentRow > notProducingStartRow && data.getUnitData().showProduction()) { reportPanel.add(createEmptyLabel(), "cell " + PRODUCTION_COLUMN + " " + notProducingStartRow - + " 1 " + (row - notProducingStartRow)); + + " 1 " + (currentRow - notProducingStartRow)); } - return row; + return currentRow; } private void addLocations() { diff --git a/src/net/sf/freecol/client/gui/panel/report/LabourData.java b/src/net/sf/freecol/client/gui/panel/report/LabourData.java index cb1eb807e2..269881eaaf 100644 --- a/src/net/sf/freecol/client/gui/panel/report/LabourData.java +++ b/src/net/sf/freecol/client/gui/panel/report/LabourData.java @@ -125,6 +125,7 @@ private void add(ProductionData data) { public static class LocationData { + @FunctionalInterface public interface Getter { LocationData getLocationData(UnitData unitData); } diff --git a/src/net/sf/freecol/client/gui/panel/report/ReportCompactColonyPanel.java b/src/net/sf/freecol/client/gui/panel/report/ReportCompactColonyPanel.java index 6d44e26101..5ff72b7aec 100644 --- a/src/net/sf/freecol/client/gui/panel/report/ReportCompactColonyPanel.java +++ b/src/net/sf/freecol/client/gui/panel/report/ReportCompactColonyPanel.java @@ -306,7 +306,6 @@ private void produce(GoodsType goodsType) { } else if (p == 0) { status = ProductionStatus.ZERO; extra = 0; - deficit = null; for (WorkLocation wl : colony.getWorkLocationsForProducing(goodsType)) { ProductionInfo pi = colony.getProductionInfo(wl); if (pi == null) continue; @@ -332,7 +331,6 @@ private void produce(GoodsType goodsType) { } else { status = ProductionStatus.GOOD; extra = 0; - deficit = null; for (WorkLocation wl : colony.getWorkLocationsForProducing(goodsType)) { ProductionInfo pi = colony.getProductionInfo(wl); if (pi == null) continue; @@ -436,8 +434,8 @@ private static StringTemplate stpl(String messageId) { } private static StringTemplate stpld(String messageId) { - messageId = Messages.descriptionKey(messageId); - return stpl(messageId); + String descriptionKey = Messages.descriptionKey(messageId); + return stpl(descriptionKey); } private JLabel newLabel(String h, ImageIcon i, Color c) { @@ -501,7 +499,8 @@ private void updateColony(ColonySummary s) { : cGood; String annotations = "", key; t = StringTemplate.label(","); - if ((building = s.colony.getStockade()) == null) { + building = s.colony.getStockade(); + if (building == null) { key = "annotation.unfortified"; t.add(Messages.message("report.colony.annotation.unfortified")); } else { @@ -514,12 +513,15 @@ private void updateColony(ColonySummary s) { if (!s.colony.getTile().isCoastland()) { key = "annotation.inland"; t.add(Messages.message("report.colony.annotation.inland")); - } else if ((building = s.colony.getWorkLocationWithAbility(Ability.PRODUCE_IN_WATER, Building.class)) == null) { + } else { + building = s.colony.getWorkLocationWithAbility(Ability.PRODUCE_IN_WATER, Building.class); + if (building == null) { key = "annotation.coastal"; t.add(Messages.message("report.colony.annotation.coastal")); - } else { - key = "annotation." + building.getType().getSuffix(); - t.add(Messages.message(building.getLabel())); + } else { + key = "annotation." + building.getType().getSuffix(); + t.add(Messages.message(building.getLabel())); + } } if (ResourceManager.getStringResource(key, false) != null) { annotations += ResourceManager.getString(key); @@ -548,7 +550,8 @@ private void updateColony(ColonySummary s) { t.add(Messages.message(building.getLabel())); if (ResourceManager.hasResource(key)) annotations += ResourceManager.getString(key); }*/ - if ((building = s.colony.getWorkLocationWithAbility(Ability.EXPORT, Building.class)) != null) { + building = s.colony.getWorkLocationWithAbility(Ability.EXPORT, Building.class); + if (building != null) { annotations += "*"; t.add(Messages.message(building.getLabel())); } @@ -1129,7 +1132,7 @@ private void update() { // Define the layout, with a column for each goods type. StringBuilder sb = new StringBuilder(64); sb.append("[l][c][c][c]"); - for (int i = 0; i < this.goodsTypes.size(); i++) sb.append("[c]"); + for (GoodsType ignored : this.goodsTypes) sb.append("[c]"); sb.append("[c][c][l][l][l]"); reportPanel.setLayout(new MigLayout("fillx, insets 0, gap 0 0", sb.toString(), "")); diff --git a/src/net/sf/freecol/client/gui/panel/report/ReportIndianPanel.java b/src/net/sf/freecol/client/gui/panel/report/ReportIndianPanel.java index 2c7abd9931..31b64be3e8 100644 --- a/src/net/sf/freecol/client/gui/panel/report/ReportIndianPanel.java +++ b/src/net/sf/freecol/client/gui/panel/report/ReportIndianPanel.java @@ -213,7 +213,8 @@ private void buildIndianAdvisorPanel(Player player, Player opponent) { JLabel goodsLabel; GoodsType gt; List gl = is.getWantedGoodsLabel(i, player); - if (visited && (gt = is.getWantedGoods(i)) != null) { + gt = is.getWantedGoods(i); + if (visited && gt != null) { goodsLabel = new JLabel(""); goodsLabel.setIcon(new ImageIcon(lib .getSmallGoodsTypeImage(gt))); diff --git a/src/net/sf/freecol/client/gui/panel/report/ReportLabourPanel.java b/src/net/sf/freecol/client/gui/panel/report/ReportLabourPanel.java index bc24889e19..b01a6b6f95 100644 --- a/src/net/sf/freecol/client/gui/panel/report/ReportLabourPanel.java +++ b/src/net/sf/freecol/client/gui/panel/report/ReportLabourPanel.java @@ -53,6 +53,7 @@ import net.sf.freecol.common.model.TypeCountMap; import net.sf.freecol.common.model.Unit; import net.sf.freecol.common.model.UnitType; +import java.util.logging.Level; /** @@ -152,7 +153,7 @@ public ReportLabourPanel(FreeColClient freeColClient) { Location location = unit.getLocation(); if (location == null) { - logger.warning("Unit has null location: " + unit); + if (logger.isLoggable(Level.WARNING)) logger.warning("Unit has null location: " + unit); } else if (location.getSettlement() != null) { location = location.getSettlement(); } else if (unit.isInEurope()) { diff --git a/src/net/sf/freecol/client/gui/panel/report/ReportRequirementsPanel.java b/src/net/sf/freecol/client/gui/panel/report/ReportRequirementsPanel.java index db68fe46b4..d76c3afc64 100644 --- a/src/net/sf/freecol/client/gui/panel/report/ReportRequirementsPanel.java +++ b/src/net/sf/freecol/client/gui/panel/report/ReportRequirementsPanel.java @@ -137,7 +137,7 @@ private void checkColony(Colony colony, StyledDocument doc) { StyleConstants.setComponent(doc.getStyle("button"), createColonyButton(colony, true)); doc.insertString(doc.getLength(), " ", doc.getStyle("button")); - } catch (Exception e) { + } catch (BadLocationException e) { logger.log(Level.WARNING, "Colony check fail", e); } @@ -217,7 +217,7 @@ private void checkColony(Colony colony, StyledDocument doc) { doc.insertString(doc.getLength(), "\n\n" + Messages.message("report.requirements.met"), doc.getStyle("regular")); - } catch (Exception e) { + } catch (BadLocationException e) { logger.log(Level.WARNING, "Colony check fail", e); } } @@ -232,7 +232,7 @@ private void addTileWarning(StyledDocument doc, Colony colony, try { doc.insertString(doc.getLength(), "\n\n" + Messages.message(t), doc.getStyle("regular")); - } catch (Exception e) { + } catch (BadLocationException e) { logger.log(Level.WARNING, "Tile warning fail", e); } } @@ -256,7 +256,7 @@ private void addBadAssignmentWarning(StyledDocument doc, Colony colony, try { doc.insertString(doc.getLength(), "\n\n" + newMessage, doc.getStyle("regular")); - } catch (Exception e) { + } catch (BadLocationException e) { logger.log(Level.WARNING, "Bad assignment fail", e); } } @@ -323,13 +323,14 @@ private void addExpertWarning(StyledDocument doc, Colony c, insertColonyButtons(doc, canTrainExperts); } - } catch(Exception e) { + } catch (BadLocationException e) { logger.log(Level.WARNING, "Assign experts fail", e); } } - private void insertColonyButtons(StyledDocument doc, List colonies) throws Exception { + private void insertColonyButtons(StyledDocument doc, List colonies) + throws BadLocationException { for (Colony colony : colonies) { StyleConstants.setComponent(doc.getStyle("button"), createColonyButton(colony, false)); doc.insertString(doc.getLength(), " ", doc.getStyle("button")); diff --git a/src/net/sf/freecol/client/gui/panel/report/ReportTurnPanel.java b/src/net/sf/freecol/client/gui/panel/report/ReportTurnPanel.java index 004a54e853..8885567c37 100644 --- a/src/net/sf/freecol/client/gui/panel/report/ReportTurnPanel.java +++ b/src/net/sf/freecol/client/gui/panel/report/ReportTurnPanel.java @@ -24,8 +24,9 @@ import java.awt.event.ActionEvent; import java.util.ArrayList; import java.util.Comparator; -import java.util.Hashtable; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; @@ -70,11 +71,11 @@ public final class ReportTurnPanel extends ReportPanel { private static final Logger logger = Logger.getLogger(ReportTurnPanel.class.getName()); /** Map message identifiers to label. */ - private final Hashtable> labelsByMessage - = new Hashtable<>(); + private final Map> labelsByMessage + = new HashMap<>(); /** Map message identifiers to text pane. */ - private final Hashtable> textPanesByMessage - = new Hashtable<>(); + private final Map> textPanesByMessage + = new HashMap<>(); /** The messages to display. */ private final List messages = new ArrayList<>(); @@ -199,14 +200,18 @@ private void displayMessages() { // them by message identifier in the ActionListeners. String id = message.getId(); List components; - if ((components = textPanesByMessage.get(id)) == null) - textPanesByMessage.put(id, - components = new ArrayList()); + components = textPanesByMessage.get(id); + if (components == null) { + components = new ArrayList(); + textPanesByMessage.put(id, components); + } components.add(textPane); - if ((components = labelsByMessage.get(id)) == null) - labelsByMessage.put(id, - components = new ArrayList()); + components = labelsByMessage.get(id); + if (components == null) { + components = new ArrayList(); + labelsByMessage.put(id, components); + } components.add(label); // Add filter button if option present. diff --git a/src/net/sf/freecol/client/gui/panel/report/ReportUnitPanel.java b/src/net/sf/freecol/client/gui/panel/report/ReportUnitPanel.java index 04ee55bd89..b8b164f2c4 100644 --- a/src/net/sf/freecol/client/gui/panel/report/ReportUnitPanel.java +++ b/src/net/sf/freecol/client/gui/panel/report/ReportUnitPanel.java @@ -64,6 +64,7 @@ public abstract class ReportUnitPanel extends ReportPanel { /** Simple comparator to order miscellaneous locations. */ private static final Comparator locationComparator = new Comparator() { + @Override public int compare(Location l1, Location l2) { return l1.getId().compareTo(l2.getId()); } @@ -89,7 +90,7 @@ public int compare(Location l1, Location l2) { private final List orderedLocations = new ArrayList<>(); /** Whether to show colonies even if no selected units are present. */ - private boolean showColonies = false; + private boolean showColonies; /** diff --git a/src/net/sf/freecol/client/gui/plaf/FreeColCheckBoxUI.java b/src/net/sf/freecol/client/gui/plaf/FreeColCheckBoxUI.java index 3923fe8368..2fbc218d2e 100644 --- a/src/net/sf/freecol/client/gui/plaf/FreeColCheckBoxUI.java +++ b/src/net/sf/freecol/client/gui/plaf/FreeColCheckBoxUI.java @@ -77,6 +77,7 @@ protected int getWidgetSize() { return FontLibrary.getMainFont().getSize() * 3 / 2; } + @Override public void paintIcon(Component c, Graphics g, int x, int y) { final Graphics2D g2d = (Graphics2D) g; final int mainFontSize = FontLibrary.getMainFont().getSize(); @@ -128,10 +129,12 @@ public void paintIcon(Component c, Graphics g, int x, int y) { } } + @Override public int getIconWidth() { return getWidgetSize(); } + @Override public int getIconHeight() { return getWidgetSize(); } diff --git a/src/net/sf/freecol/client/gui/plaf/FreeColComboBoxRenderer.java b/src/net/sf/freecol/client/gui/plaf/FreeColComboBoxRenderer.java index 0f6dad798c..bccdd9ae07 100644 --- a/src/net/sf/freecol/client/gui/plaf/FreeColComboBoxRenderer.java +++ b/src/net/sf/freecol/client/gui/plaf/FreeColComboBoxRenderer.java @@ -40,6 +40,7 @@ import net.sf.freecol.common.option.AudioMixerOption.MixerWrapper; import net.sf.freecol.common.option.FullscreenDisplayModeOption.FullscreenDisplayModeWrapper; import net.sf.freecol.common.option.LanguageOption.Language; +import java.util.logging.Level; /** @@ -162,7 +163,7 @@ protected void setLabelValues(JLabel c, T value) { final FullscreenDisplayModeWrapper fdw = (FullscreenDisplayModeWrapper) value; c.setText(fdw.getName()); } else { - logger.warning("What is this?: " + value + if (logger.isLoggable(Level.WARNING)) logger.warning("What is this?: " + value + " (" + value.getClass() + ")"); } } diff --git a/src/net/sf/freecol/client/gui/plaf/FreeColListUI.java b/src/net/sf/freecol/client/gui/plaf/FreeColListUI.java index 819d1da594..ca610c7463 100644 --- a/src/net/sf/freecol/client/gui/plaf/FreeColListUI.java +++ b/src/net/sf/freecol/client/gui/plaf/FreeColListUI.java @@ -40,11 +40,6 @@ public static ComponentUI createUI(@SuppressWarnings("unused") JComponent c) { } - @Override - public void installUI(JComponent c) { - super.installUI(c); - } - @Override public void paint(Graphics g, JComponent c) { ImageUtils.drawTiledImage(ImageLibrary.getListBackground(), diff --git a/src/net/sf/freecol/client/gui/plaf/FreeColOptionPaneUI.java b/src/net/sf/freecol/client/gui/plaf/FreeColOptionPaneUI.java index 04ee5abf39..2661a48cfd 100644 --- a/src/net/sf/freecol/client/gui/plaf/FreeColOptionPaneUI.java +++ b/src/net/sf/freecol/client/gui/plaf/FreeColOptionPaneUI.java @@ -100,10 +100,12 @@ public void setInitialFocusComponent(Component component) { */ content.setFocusable(true); initialFocusComponent.addHierarchyListener(new HierarchyListener() { + @Override public void hierarchyChanged(HierarchyEvent e) { final Component c = e.getComponent(); if (c.isShowing() && (e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) { SwingUtilities.invokeLater(new Runnable() { + @Override public void run() { content.setFocusable(false); c.requestFocus(); @@ -155,6 +157,8 @@ private List prepareButtons() { final String cancelLabel = Messages.message("cancel"); Object[] buttons = getButtons(); List newButtons = new ArrayList<>(buttons.length); + int okIndex = -1; + int cancelIndex = -1; int maxWidth = 0, maxHeight = 0; for (int i = 0; i < buttons.length; i++) { @@ -166,8 +170,8 @@ private List prepareButtons() { b = (label == null || label.isEmpty()) ? new JButton(icon) : new JButton(label, icon); b.setName("OptionPane.button." + label); - if (ci.isOK()) this.okIndex = i; - else if (ci.isCancel()) this.cancelIndex = i; + if (ci.isOK()) okIndex = i; + else if (ci.isCancel()) cancelIndex = i; } else if (buttons[i] instanceof Icon) { b = new JButton((Icon)buttons[i]); b.setName("OptionPane.button.withIcon"); @@ -175,8 +179,8 @@ private List prepareButtons() { String label = buttons[i].toString(); b = new JButton(label); b.setName("OptionPane.button." + label); - if (okLabel.equals(label)) this.okIndex = i; - else if (cancelLabel.equals(label)) this.cancelIndex = i; + if (okLabel.equals(label)) okIndex = i; + else if (cancelLabel.equals(label)) cancelIndex = i; } maxWidth = Math.max(maxWidth, b.getMinimumSize().width); maxHeight = Math.max(maxHeight, b.getMinimumSize().height); @@ -184,6 +188,8 @@ private List prepareButtons() { b.addActionListener(buttonListener); newButtons.add(b); } + this.okIndex = okIndex; + this.cancelIndex = cancelIndex; if (maxWidth > 0) { Dimension dimension = new Dimension(maxWidth, maxHeight); for (int i = 0; i < buttons.length; i++) { @@ -210,7 +216,10 @@ private JButton getButton(int index) { // Override BasicOptionPaneUI /** - * {@inheritDoc} + * Creates a new UI delegate for a {@code JOptionPane}. + * + * @param c The component to create a UI for. + * @return The new UI delegate. */ public static ComponentUI createUI(@SuppressWarnings("unused")JComponent c) { return new FreeColOptionPaneUI(); diff --git a/src/net/sf/freecol/client/gui/plaf/FreeColRadioButtonUI.java b/src/net/sf/freecol/client/gui/plaf/FreeColRadioButtonUI.java index ee4ad75f47..38f066ed5e 100644 --- a/src/net/sf/freecol/client/gui/plaf/FreeColRadioButtonUI.java +++ b/src/net/sf/freecol/client/gui/plaf/FreeColRadioButtonUI.java @@ -74,6 +74,7 @@ protected int getWidgetSize() { return FontLibrary.getMainFont().getSize() * 3 / 2; } + @Override public void paintIcon(Component c, Graphics g, int x, int y) { final Graphics2D g2d = (Graphics2D) g; final ButtonModel model = ((AbstractButton) c).getModel(); @@ -115,10 +116,12 @@ public void paintIcon(Component c, Graphics g, int x, int y) { } } + @Override public int getIconWidth() { return getWidgetSize(); } + @Override public int getIconHeight() { return getWidgetSize(); } diff --git a/src/net/sf/freecol/client/gui/video/VideoComponent.java b/src/net/sf/freecol/client/gui/video/VideoComponent.java index d479481456..5c0b5039e9 100644 --- a/src/net/sf/freecol/client/gui/video/VideoComponent.java +++ b/src/net/sf/freecol/client/gui/video/VideoComponent.java @@ -189,7 +189,7 @@ public void removeNotify() { // all cases: try { super.removeNotify(); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { logger.log(Level.WARNING, "Video removal crash", e); } } diff --git a/src/net/sf/freecol/client/gui/video/VideoListener.java b/src/net/sf/freecol/client/gui/video/VideoListener.java index 54435b0758..50964c6979 100644 --- a/src/net/sf/freecol/client/gui/video/VideoListener.java +++ b/src/net/sf/freecol/client/gui/video/VideoListener.java @@ -22,6 +22,7 @@ /** * A listener for video playback events. */ +@FunctionalInterface public interface VideoListener { /** diff --git a/src/net/sf/freecol/client/package-info.java b/src/net/sf/freecol/client/package-info.java index b81c87ca6c..5d461b03d2 100644 --- a/src/net/sf/freecol/client/package-info.java +++ b/src/net/sf/freecol/client/package-info.java @@ -1,5 +1,5 @@ /** - *

FreeCol Client Package

+ *

FreeCol Client Package

* *

This is the main client package.

* diff --git a/src/net/sf/freecol/common/FreeColSeed.java b/src/net/sf/freecol/common/FreeColSeed.java index ae37961bfc..382049e662 100644 --- a/src/net/sf/freecol/common/FreeColSeed.java +++ b/src/net/sf/freecol/common/FreeColSeed.java @@ -20,6 +20,8 @@ package net.sf.freecol.common; import java.security.SecureRandom; +import java.util.logging.Level; +import java.util.logging.Logger; /** @@ -27,6 +29,8 @@ */ public class FreeColSeed { + private static final Logger logger = Logger.getLogger(FreeColSeed.class.getName()); + public static final long DEFAULT_SEED = 0L; /** The seed to use for pseudo-random number generators. */ @@ -72,7 +76,9 @@ public static boolean setFreeColSeed(String arg) { FreeColSeed.freeColSeed = Long.parseLong(arg); FreeColSeed.seeded = true; return true; - } catch (NumberFormatException nfe) {} + } catch (NumberFormatException nfe) { + if (logger.isLoggable(Level.FINE)) logger.log(Level.FINE, "Invalid seed: " + arg, nfe); + } return false; } } diff --git a/src/net/sf/freecol/common/FreeColUserMessageException.java b/src/net/sf/freecol/common/FreeColUserMessageException.java index e4765bdd3f..b51162a847 100644 --- a/src/net/sf/freecol/common/FreeColUserMessageException.java +++ b/src/net/sf/freecol/common/FreeColUserMessageException.java @@ -35,7 +35,7 @@ public final class FreeColUserMessageException extends RuntimeException { /** * Build a new FreeCol specific exception with the given message. * - * @param message The message for this exception. + * @param stringTemplate The message for this exception. */ public FreeColUserMessageException(StringTemplate stringTemplate) { super(Messages.message(Objects.requireNonNull(stringTemplate))); diff --git a/src/net/sf/freecol/common/ObjectWithId.java b/src/net/sf/freecol/common/ObjectWithId.java index 05c035b17a..501145c1bd 100644 --- a/src/net/sf/freecol/common/ObjectWithId.java +++ b/src/net/sf/freecol/common/ObjectWithId.java @@ -24,6 +24,7 @@ * Any object that provides a string identifier that can be used to * identify it, and to provide a localized name for it. */ +@FunctionalInterface public interface ObjectWithId { /** diff --git a/src/net/sf/freecol/common/debug/DebugUtils.java b/src/net/sf/freecol/common/debug/DebugUtils.java index 5fee72b6ef..1f028d21bd 100644 --- a/src/net/sf/freecol/common/debug/DebugUtils.java +++ b/src/net/sf/freecol/common/debug/DebugUtils.java @@ -28,7 +28,11 @@ import java.util.Set; import java.util.function.Function; import java.util.function.Predicate; +import java.util.logging.Level; import java.util.logging.Logger; +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.nio.charset.StandardCharsets; import javax.swing.JMenu; import javax.swing.JMenuItem; @@ -655,9 +659,8 @@ private static void checkDesyncTile(Game cGame, ServerPlayer sPlayer, su.getDescription(Unit.UnitLabelType.NATIONAL), "(", su.getId(), ") from: ", su.getLocation().getId(), ".\n"); - try { - lb.add(" Client: ", cTile.getFirstUnit(), "\n"); - } catch (NullPointerException npe) {} + Unit firstUnit = (cTile == null) ? null : cTile.getFirstUnit(); + lb.add(" Client: ", firstUnit, "\n"); } else { if (cu.hasTile() && !cu.getTile().getId().equals(su.getTile().getId())) { @@ -893,15 +896,21 @@ public static void dumpTile(final FreeColClient freeColClient, final Game sGame = server.getGame(); final Player player = freeColClient.getMyPlayer(); - System.err.println("\nClient (" + game.getClientUserName() - + "/" + player.getId() + "):"); - tile.save(System.err, WriteScope.toClient(player), true); - System.err.println("\n\nServer:"); - Tile sTile = sGame.getFreeColGameObject(tile.getId(), Tile.class); - sTile.save(System.err, WriteScope.toServer(), true); - System.err.println("\n\nSave:"); - sTile.save(System.err, WriteScope.toSave(), true); - System.err.println('\n'); + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + try (PrintStream ps = new PrintStream(bos, true, StandardCharsets.UTF_8)) { + ps.println("\nClient (" + game.getClientUserName() + + "/" + player.getId() + "):"); + tile.save(ps, WriteScope.toClient(player), true); + ps.println("\n\nServer:"); + Tile sTile = sGame.getFreeColGameObject(tile.getId(), Tile.class); + sTile.save(ps, WriteScope.toServer(), true); + ps.println("\n\nSave:"); + sTile.save(ps, WriteScope.toSave(), true); + ps.println('\n'); + } + if (logger.isLoggable(Level.INFO)) { + logger.info(new String(bos.toByteArray(), StandardCharsets.UTF_8)); + } } /** diff --git a/src/net/sf/freecol/common/debug/FreeColDebugger.java b/src/net/sf/freecol/common/debug/FreeColDebugger.java index ed0776c501..e325664cc9 100644 --- a/src/net/sf/freecol/common/debug/FreeColDebugger.java +++ b/src/net/sf/freecol/common/debug/FreeColDebugger.java @@ -28,6 +28,7 @@ import static java.nio.file.StandardOpenOption.*; import java.util.concurrent.atomic.AtomicReference; +import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; @@ -193,8 +194,8 @@ public static boolean setDebugModes(String optionValue) { try { DebugMode mode = Enum.valueOf(DebugMode.class, upCase(s)); enableDebugMode(mode); - } catch (RuntimeException e) { - logger.warning("Unrecognized debug mode: " + optionValue); + } catch (IllegalArgumentException e) { + if (logger.isLoggable(Level.WARNING)) logger.warning("Unrecognized debug mode: " + optionValue); return false; } } @@ -295,7 +296,9 @@ public static boolean finishDebugRun(FreeColClient freeColClient, try { fcs.saveGame(FreeColDirectories.getDebugRunSaveFile(), freeColClient.getClientOptions(), null); - } catch (IOException e) {} + } catch (IOException e) { + logger.log(Level.FINE, "Failed to save debug run.", e); + } } freeColClient.quit(); } @@ -497,9 +500,10 @@ public static void trace(Logger logger, String warn) { lb.add(warn, "\n"); addStackTrace(lb); if (logger == null) { - System.err.println(lb.toString()); + Logger fallbackLogger = Logger.getLogger(FreeColDebugger.class.getName()); + if (fallbackLogger.isLoggable(Level.WARNING)) fallbackLogger.warning(lb.toString()); } else { - logger.warning(lb.toString()); + if (logger.isLoggable(Level.WARNING)) logger.warning(lb.toString()); } } } diff --git a/src/net/sf/freecol/common/i18n/Messages.java b/src/net/sf/freecol/common/i18n/Messages.java index 8eb9fb6ba4..db2c772f4f 100644 --- a/src/net/sf/freecol/common/i18n/Messages.java +++ b/src/net/sf/freecol/common/i18n/Messages.java @@ -34,6 +34,7 @@ import java.util.AbstractMap.SimpleEntry; import java.util.HashMap; import java.util.List; +import java.util.IllformedLocaleException; import java.util.Locale; import java.util.Map; import java.util.StringTokenizer; @@ -145,8 +146,8 @@ public static void setGrammaticalNumber(Number number) { /** * Load the message bundle for the given locale * - * Error messages have to go to System.err as this routine is called - * before logging is enabled. + * Error messages go to the logger as this routine can run before + * logging is configured. * * @param locale The {@code Locale} to set resources for. */ @@ -160,12 +161,16 @@ public static void loadMessageBundle(Locale locale) { try (InputStream in = Files.newInputStream(cldr.toPath())) { NumberRules.load(in); } catch (IOException|XMLStreamException e) { - System.err.println("Failed to read CLDR rules: " - + e.getMessage()); + if (logger.isLoggable(Level.WARNING)) { + logger.warning("Failed to read CLDR rules: " + + e.getMessage()); + } } } else { - System.err.println("Could not find CLDR rules: " - + cldr.getPath()); + if (logger.isLoggable(Level.WARNING)) { + logger.warning("Could not find CLDR rules: " + + cldr.getPath()); + } } } @@ -178,8 +183,10 @@ public static void loadMessageBundle(Locale locale) { try { loadMessages(Files.newInputStream(f.toPath())); } catch (IOException ioe) { - System.err.println("Failed to load messages from " - + f.getPath() + ": " + ioe.getMessage()); + if (logger.isLoggable(Level.WARNING)) { + logger.warning("Failed to load messages from " + + f.getPath() + ": " + ioe.getMessage()); + } } } @@ -187,20 +194,18 @@ public static void loadMessageBundle(Locale locale) { = FreeColDirectories.getMessageFileNameList(locale); for (FreeColModFile fctf : FreeColRules.getRulesList()) { for (String fn : filenames) { - InputStream is = null; - try { - is = fctf.getInputStream(fn); + try (InputStream is = fctf.getInputStream(fn)) { + try { + loadMessages(is); + } catch (IOException ioe) { + if (logger.isLoggable(Level.WARNING)) { + logger.warning("Failed to load rules messages from " + + fn + ": " + ioe.getMessage()); + } + } } catch (IOException ioe) { continue; // Expecting failure } - try { - loadMessages(is); - } catch (IOException ioe) { - System.err.println("Failed to load rules messages from " - + fn + ": " + ioe.getMessage()); - } finally { - try { is.close(); } catch (IOException x) {} - } } } } @@ -217,7 +222,7 @@ public static void loadMessageBundle(Locale locale) { */ public static void loadMessages(InputStream is) throws IOException { try (BufferedReader in = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) { - String line = null; + String line; while((line = in.readLine()) != null) { line = line.trim(); int index = line.indexOf('#'); @@ -325,7 +330,15 @@ public static Locale getLocale(String languageID) { } } } - return new Locale(language, country, variant); + try { + Locale.Builder builder = new Locale.Builder(); + if (!language.isEmpty()) builder.setLanguage(language); + if (!country.isEmpty()) builder.setRegion(country); + if (!variant.isEmpty()) builder.setVariant(variant); + return builder.build(); + } catch (IllformedLocaleException e) { + return Locale.ROOT; + } } @@ -737,7 +750,7 @@ public static String message(StringTemplate template) { if (sb.length() >= template.getId().length()) { result = sb.toString().substring(template.getId().length()); } else { - logger.warning("incorrect use of template " + template); + if (logger.isLoggable(Level.WARNING)) logger.warning("incorrect use of template " + template); } } break; @@ -786,8 +799,8 @@ public static String message(StringTemplate template) { * @return a {@code String} value */ private static String replaceChoices(String input, StringTemplate template) { - int openChoice = 0; - int closeChoice = 0; + int openChoice; + int closeChoice; int highWaterMark = 0; StringBuilder result = new StringBuilder(); while ((openChoice = input.indexOf("{{", highWaterMark)) >= 0) { @@ -795,19 +808,19 @@ private static String replaceChoices(String input, StringTemplate template) { closeChoice = findMatchingBracket(input, openChoice + 2); if (closeChoice < 0) { // no closing brackets found - logger.warning("Mismatched brackets: " + input); + if (logger.isLoggable(Level.WARNING)) logger.warning("Mismatched brackets: " + input); return result.toString(); } highWaterMark = closeChoice + 2; int colonIndex = input.indexOf(':', openChoice + 2); if (colonIndex < 0 || colonIndex > closeChoice) { - logger.warning("No tag found: " + input); + if (logger.isLoggable(Level.WARNING)) logger.warning("No tag found: " + input); continue; } String tag = input.substring(openChoice + 2, colonIndex); int pipeIndex = input.indexOf('|', colonIndex + 1); if (pipeIndex < 0 || pipeIndex > closeChoice) { - logger.warning("No choices found: " + input); + if (logger.isLoggable(Level.WARNING)) logger.warning("No choices found: " + input); continue; } String selector = input.substring(colonIndex + 1, pipeIndex); @@ -820,7 +833,7 @@ private static String replaceChoices(String input, StringTemplate template) { StringTemplate replacement = template.getReplacement(selector); if (replacement == null) { - logger.warning("Failed to find replacement for " + if (logger.isLoggable(Level.WARNING)) logger.warning("Failed to find replacement for " + selector); continue; } else { @@ -846,7 +859,7 @@ private static String replaceChoices(String input, StringTemplate template) { StringTemplate replacement = template.getReplacement(otherKey); if (replacement == null) { - logger.warning("Failed to find replacement for " + if (logger.isLoggable(Level.WARNING)) logger.warning("Failed to find replacement for " + selector + "/" + otherKey); continue; } else if (replacement.getTemplateType() == TemplateType.KEY) { @@ -858,7 +871,7 @@ private static String replaceChoices(String input, StringTemplate template) { } else { keyIndex = otherKey.indexOf(selector, keyIndex); if (keyIndex < 0) { - logger.warning("Failed to find key " + if (logger.isLoggable(Level.WARNING)) logger.warning("Failed to find key " + selector + "/" + otherKey + " in replacement " + replacement); continue; @@ -867,7 +880,7 @@ private static String replaceChoices(String input, StringTemplate template) { } } } else { - logger.warning("Choice substitution for " + if (logger.isLoggable(Level.WARNING)) logger.warning("Choice substitution for " + selector + "/" + otherKey + " attempted, but template was " + replacement + " for input " + input); @@ -877,7 +890,7 @@ private static String replaceChoices(String input, StringTemplate template) { otherKey = getChoice(messageBundle.get(otherKey), selector); result.append(otherKey); } else { - logger.warning("Unknown key or untagged choice: '" + if (logger.isLoggable(Level.WARNING)) logger.warning("Unknown key or untagged choice: '" + otherKey + "', selector was '" + selector + "', trying 'default' instead"); @@ -938,7 +951,7 @@ private static String getChoice(String input, String key) { if (end < 0) { end = input.indexOf("}}", start); if (end < 0) { - logger.warning("Failed to find end of choice for key " + key + if (logger.isLoggable(Level.WARNING)) logger.warning("Failed to find end of choice for key " + key + " in input " + input); return null; } diff --git a/src/net/sf/freecol/common/i18n/NameCache.java b/src/net/sf/freecol/common/i18n/NameCache.java index 557e823455..97a0f93be9 100644 --- a/src/net/sf/freecol/common/i18n/NameCache.java +++ b/src/net/sf/freecol/common/i18n/NameCache.java @@ -36,6 +36,7 @@ import static net.sf.freecol.common.util.RandomUtils.*; import static net.sf.freecol.common.util.StringUtils.*; +import java.util.logging.Level; /** @@ -106,8 +107,8 @@ public class NameCache { * @param names A list to fill with the names found. */ private static void collectNames(String prefix, List names) { - String name; - if (Messages.containsKey(name = prefix + "0")) { + String name = prefix + "0"; + if (Messages.containsKey(name)) { names.add(Messages.message(name)); } int i = 1; @@ -303,7 +304,7 @@ private static void requireSettlementNames(Player player, Random random) { } } settlementNames.put(player, names); - logger.fine("Loaded " + names.size() + " settlement names for " + if (logger.isLoggable(Level.FINE)) logger.fine("Loaded " + names.size() + " settlement names for " + player.getId()); } } @@ -536,7 +537,7 @@ public static String getSettlementName(Player player, Random random) { // Use the fallback name final String base = getFallbackSettlementName(player); int i = player.getSettlementCount() + 1; - String name = null; + String name; while (game.getSettlementByName(name = base + i++) != null); return name; } diff --git a/src/net/sf/freecol/common/i18n/Number.java b/src/net/sf/freecol/common/i18n/Number.java index 0e736eaced..755b0d9570 100644 --- a/src/net/sf/freecol/common/i18n/Number.java +++ b/src/net/sf/freecol/common/i18n/Number.java @@ -20,6 +20,7 @@ package net.sf.freecol.common.i18n; import java.util.logging.Logger; +import java.util.logging.Level; /** @@ -52,7 +53,7 @@ public String getKey(String selector, String template) { try { return getKey(Double.parseDouble(selector)); } catch(NumberFormatException e) { - logger.warning("Syntax error in string template '" + template + "'"); + if (logger.isLoggable(Level.WARNING)) logger.warning("Syntax error in string template '" + template + "'"); return Category.other.toString(); } } diff --git a/src/net/sf/freecol/common/i18n/Selector.java b/src/net/sf/freecol/common/i18n/Selector.java index 98ace0105d..233a189dfd 100644 --- a/src/net/sf/freecol/common/i18n/Selector.java +++ b/src/net/sf/freecol/common/i18n/Selector.java @@ -19,6 +19,7 @@ package net.sf.freecol.common.i18n; +@FunctionalInterface public interface Selector { /** diff --git a/src/net/sf/freecol/common/i18n/package-info.java b/src/net/sf/freecol/common/i18n/package-info.java index 4b99523ab7..595ab327f8 100644 --- a/src/net/sf/freecol/common/i18n/package-info.java +++ b/src/net/sf/freecol/common/i18n/package-info.java @@ -1,5 +1,5 @@ /** - *

FreeCol Internationalisation package

+ *

FreeCol Internationalisation package

* *

This package contains the FreeCol support for internationalisation * (translation). diff --git a/src/net/sf/freecol/common/io/FreeColDataFile.java b/src/net/sf/freecol/common/io/FreeColDataFile.java index 2c9040bf44..374c690998 100644 --- a/src/net/sf/freecol/common/io/FreeColDataFile.java +++ b/src/net/sf/freecol/common/io/FreeColDataFile.java @@ -117,7 +117,7 @@ private static String findJarDirectory(File file) { } return name; } catch (IOException ioe) { - logger.warning("Failed to create jar file: " + file.getName()); + if (logger.isLoggable(Level.WARNING)) logger.warning("Failed to create jar file: " + file.getName()); } return null; } @@ -134,7 +134,7 @@ protected URI getURI(String name) { try { return new URI(name); } catch (URISyntaxException e) { - logger.log(Level.WARNING, "Resource creation failure with: " + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Resource creation failure with: " + name, e); return null; } @@ -145,7 +145,7 @@ protected URI getURI(String name) { null); } } catch (URISyntaxException e) { - logger.log(Level.WARNING, "Failed to lookup: " + file + "/" + name, + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Failed to lookup: " + file + "/" + name, e); return null; } @@ -309,7 +309,7 @@ private Properties readResourcesProperties(final LogBuilder lb) { } catch (FileNotFoundException e) { // Expected failure lb.add(' ', file, '/', fileName, ":not-found"); } catch (IOException e) { - logger.log(Level.WARNING, "ResourceMapping read exception: " + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "ResourceMapping read exception: " + file + "/" + fileName, e); return null; } @@ -342,49 +342,47 @@ private Map> findVariationsWithAlternateSizes(String name) { return Map.of(); } - FileSystem fileSystem = null; try { - final Path filePath; if (file.isDirectory()) { - filePath = new File(file, name).toPath(); - } else { - /* - * We can use JarEntry instead, if this solution causes problems. - */ - fileSystem = FileSystems.newFileSystem(new URI("jar:file", file.getAbsolutePath(), null), Map.of()); - filePath = fileSystem.getPath(jarDirectory + name); + return findVariationsWithAlternateSizes(new File(file, name).toPath()); } /* - * Using LinkedHashMap to ensure we keep the variations in order. + * We can use JarEntry instead, if this solution causes problems. */ - final Map> result = new LinkedHashMap<>(); - if (MemoryManager.isHighQualityGraphicsEnabled()) { - result.put(null, findFilesWithVariationOrAlternativeSizeAsUri(filePath, false)); - } else { - result.put(null, List.of()); + try (FileSystem fileSystem = FileSystems.newFileSystem( + new URI("jar:file", file.getAbsolutePath(), null), Map.of())) { + Path filePath = fileSystem.getPath(jarDirectory + name); + return findVariationsWithAlternateSizes(filePath); } - - final List variations = findFilesWithVariationOrAlternativeSize(filePath, true); - for (Path variationPath : variations) { - if (MemoryManager.isHighQualityGraphicsEnabled()) { - result.put(variationPath.toUri(), findFilesWithVariationOrAlternativeSizeAsUri(variationPath, false)); - } else { - result.put(variationPath.toUri(), List.of()); - } - } - - return result; } catch (IOException | URISyntaxException e) { - logger.log(Level.WARNING, "Failed to read directory from jar/zip file: " + file + " jarDirectory" + jarDirectory, e); + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Failed to read directory from jar/zip file: " + file + " jarDirectory" + jarDirectory, e); return Map.of(); - } finally { - if (fileSystem != null) { - try { - fileSystem.close(); - } catch (IOException e) {} + } + } + + private Map> findVariationsWithAlternateSizes(Path filePath) throws IOException { + /* + * Using LinkedHashMap to ensure we keep the variations in order. + */ + final Map> result = new LinkedHashMap<>(); + if (MemoryManager.isHighQualityGraphicsEnabled()) { + result.put(null, findFilesWithVariationOrAlternativeSizeAsUri(filePath, false)); + } else { + result.put(null, List.of()); + } + + final List variations = findFilesWithVariationOrAlternativeSize(filePath, true); + for (Path variationPath : variations) { + if (MemoryManager.isHighQualityGraphicsEnabled()) { + result.put(variationPath.toUri(), + findFilesWithVariationOrAlternativeSizeAsUri(variationPath, false)); + } else { + result.put(variationPath.toUri(), List.of()); } } + + return result; } private List findFilesWithVariationOrAlternativeSizeAsUri(final Path filePath, boolean findVariation) throws IOException { @@ -438,7 +436,7 @@ public String getPath() { */ public static FileFilter getFileFilter(String extension) { String s = Messages.message("filter." + extension); - if (extension.equals("*")) { + if ("*".equals(extension)) { return new FileFilter() { @Override public boolean accept(File f) { diff --git a/src/net/sf/freecol/common/io/FreeColDirectories.java b/src/net/sf/freecol/common/io/FreeColDirectories.java index 16e6f374e4..264f125ccc 100644 --- a/src/net/sf/freecol/common/io/FreeColDirectories.java +++ b/src/net/sf/freecol/common/io/FreeColDirectories.java @@ -23,6 +23,8 @@ import java.io.Writer; import java.nio.file.Files; import java.nio.file.attribute.PosixFilePermission; +import java.util.logging.Level; +import java.util.logging.Logger; import java.util.ArrayList; import java.util.Collections; @@ -51,6 +53,8 @@ */ public class FreeColDirectories { + private static final Logger logger = Logger.getLogger(FreeColDirectories.class.getName()); + // No logger! Many of these routines are called before logging is // initialized. @@ -300,8 +304,10 @@ private static File requireDirectory(File dir) { Files.setPosixFilePermissions(dir.toPath(), mode0700); } catch (IOException|UnsupportedOperationException ex) { // Just log, error is not fatal - System.err.println("Failed to change permissions of " - + dir.getPath()); + if (logger.isLoggable(Level.WARNING)) { + logger.warning("Failed to change permissions of " + + dir.getPath()); + } } return dir; } @@ -349,7 +355,7 @@ private static StringTemplate badCache(File f) { * XDG directory if it is present or created. * @return Null on success, an error message on error. */ - private static StringTemplate getXDGDirs(File[] dirs) { + private static StringTemplate getXDGDirs(File... dirs) { File home = getUserDefaultDirectory(); if (home == null) return badHome(); @@ -357,25 +363,31 @@ private static StringTemplate getXDGDirs(File[] dirs) { File d = (env != null) ? new File(env) : new File(home, XDG_CONFIG_HOME_DEFAULT); File xd; - if ((xd = requireDirectory(d)) == null) return badDir(d); + xd = requireDirectory(d); + if (xd == null) return badDir(d); File f = new File(xd, FREECOL_DIRECTORY); - if ((d = requireDirectory(f)) == null) return badConfig(f); + d = requireDirectory(f); + if (d == null) return badConfig(f); dirs[0] = d; env = System.getenv(XDG_DATA_HOME_ENV); d = (env != null) ? new File(env) : new File(home, XDG_DATA_HOME_DEFAULT); - if ((xd = requireDirectory(d)) == null) return badDir(d); + xd = requireDirectory(d); + if (xd == null) return badDir(d); f = new File(xd, FREECOL_DIRECTORY); - if ((d = requireDirectory(f)) == null) return badData(f); + d = requireDirectory(f); + if (d == null) return badData(f); dirs[1] = d; env = System.getenv(XDG_CACHE_HOME_ENV); d = (env != null) ? new File(env) : new File(home, XDG_CACHE_HOME_DEFAULT); - if ((xd = requireDirectory(d)) == null) return badDir(d); + xd = requireDirectory(d); + if (xd == null) return badDir(d); f = new File(xd, FREECOL_DIRECTORY); - if ((d = requireDirectory(f)) == null) return badCache(f); + d = requireDirectory(f); + if (d == null) return badCache(f); dirs[2] = d; return null; @@ -390,7 +402,7 @@ private static StringTemplate getXDGDirs(File[] dirs) { * MacOSX freecol directories. * @return Null on success, an error message on failure. */ - private static StringTemplate getMacOSXDirs(File[] dirs) { + private static StringTemplate getMacOSXDirs(File... dirs) { File home = getUserDefaultDirectory(); if (home == null) return badHome(); File libDir = new File(home, "Library"); @@ -428,7 +440,7 @@ private static StringTemplate getMacOSXDirs(File[] dirs) { * Windows freecol directories. * @return Null on success, an error message on failure. */ - private static StringTemplate getWindowsDirs(File[] dirs) { + private static StringTemplate getWindowsDirs(File... dirs) { File home = getUserDefaultDirectory(); if (home == null) return badHome(); @@ -448,17 +460,22 @@ private static StringTemplate getWindowsDirs(File[] dirs) { private static boolean insistDirectory(File file) { boolean ret; if (file.exists()) { - if (!(ret = file.isDirectory())) { - System.err.println("Could not create directory " - + file.getPath() + " because a non-directory with that name is already there."); + ret = file.isDirectory(); + if (!ret) { + if (logger.isLoggable(Level.WARNING)) { + logger.warning("Could not create directory " + + file.getPath() + " because a non-directory with that name is already there."); + } } } else { try { ret = file.mkdir(); - } catch (Exception e) { + } catch (SecurityException e) { ret = false; - System.err.println("Could not make directory " + file.getPath() - + ": " + e.getMessage()); + if (logger.isLoggable(Level.WARNING)) { + logger.warning("Could not make directory " + file.getPath() + + ": " + e.getMessage()); + } } } return ret; @@ -754,11 +771,9 @@ public static File getClientOptionsFile() { */ public static boolean setClientOptionsFile(String path) { File file = new File(path); - if (file.exists() && file.isFile() && file.canRead()) { - clientOptionsFile = file; - return true; - } - return false; + if (!file.exists() || !file.isFile() || !file.canRead()) return false; + clientOptionsFile = file; + return true; } /** diff --git a/src/net/sf/freecol/common/io/FreeColModFile.java b/src/net/sf/freecol/common/io/FreeColModFile.java index f54d39e028..39083bcf56 100644 --- a/src/net/sf/freecol/common/io/FreeColModFile.java +++ b/src/net/sf/freecol/common/io/FreeColModFile.java @@ -115,8 +115,8 @@ public Specification getSpecification() throws IOException, return (si == null) ? null : new Specification(si); } catch (FreeColUserMessageException e) { throw e; - } catch (RuntimeException rte) { - logger.log(Level.WARNING, "Parse error while reading specification " + getId(), rte); + } catch (IllegalArgumentException | IllegalStateException rte) { + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Parse error while reading specification " + getId(), rte); throw new FreeColUserMessageException( StringTemplate.template("error.mod").add("%id%", getId()).add("%name%", Messages.getName("mod." + getId())), rte @@ -173,7 +173,7 @@ public static List getModsList() { try { ret.add(new FreeColModFile(f)); } catch (IOException ioe) { - logger.log(Level.WARNING, "Failed to load mod from: " + f, ioe); + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Failed to load mod from: " + f, ioe); } } return ret; diff --git a/src/net/sf/freecol/common/io/FreeColRules.java b/src/net/sf/freecol/common/io/FreeColRules.java index cb3c73f300..71ce9e4656 100644 --- a/src/net/sf/freecol/common/io/FreeColRules.java +++ b/src/net/sf/freecol/common/io/FreeColRules.java @@ -47,7 +47,7 @@ public static List getRulesList() { try { ret.add(new FreeColModFile(f)); } catch (IOException ioe) { - logger.log(Level.WARNING, "Failed to load TC from: " + f, ioe); + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Failed to load TC from: " + f, ioe); } } return ret; diff --git a/src/net/sf/freecol/common/io/FreeColSavegameFile.java b/src/net/sf/freecol/common/io/FreeColSavegameFile.java index 9c9aa6b7ee..5467881aa9 100644 --- a/src/net/sf/freecol/common/io/FreeColSavegameFile.java +++ b/src/net/sf/freecol/common/io/FreeColSavegameFile.java @@ -29,6 +29,8 @@ import java.io.InputStream; import java.util.List; import java.util.Properties; +import java.util.logging.Level; +import java.util.logging.Logger; import javax.xml.stream.XMLStreamException; @@ -40,6 +42,8 @@ */ public class FreeColSavegameFile extends FreeColDataFile { + private static final Logger logger = Logger.getLogger(FreeColSavegameFile.class.getName()); + /** The tag for the version string in the saved game. */ public static final String VERSION_TAG = "version"; @@ -130,7 +134,9 @@ public int getSavegameVersion() throws IOException, XMLStreamException { if (v != null && v.size() == 1) { try { ret = Integer.parseInt(v.get(0)); - } catch (NumberFormatException nfe) {} + } catch (NumberFormatException nfe) { + if (logger.isLoggable(Level.FINE)) logger.log(Level.FINE, "Invalid savegame version: " + v.get(0), nfe); + } } return ret; } diff --git a/src/net/sf/freecol/common/io/FreeColXMLReader.java b/src/net/sf/freecol/common/io/FreeColXMLReader.java index 9baf7ab361..89d51d47d9 100644 --- a/src/net/sf/freecol/common/io/FreeColXMLReader.java +++ b/src/net/sf/freecol/common/io/FreeColXMLReader.java @@ -131,7 +131,7 @@ public FreeColXMLReader(BufferedInputStream bis) try { xsr = xif.createXMLStreamReader(bis, "UTF-8"); setParent(xsr); - } catch (Exception ex) { + } catch (XMLStreamException | IllegalArgumentException ex) { throw new XMLStreamException("Stream reader fail", ex); } this.inputStream = bis; @@ -361,17 +361,19 @@ public String readId() { public int nextTag() throws XMLStreamException { int tag = super.nextTag(); if (tracing) { - switch (tag) { - case XMLStreamConstants.START_ELEMENT: - System.err.println("[" + getLocalName()); - break; - case XMLStreamConstants.END_ELEMENT: - System.err.println(getLocalName() + "]"); - break; - default: - String val = tagStrings.get(tag); - System.err.println((val == null) ? "Weird tag: " + tag : val); - break; + if (logger.isLoggable(Level.FINE)) { + switch (tag) { + case XMLStreamConstants.START_ELEMENT: + logger.fine("[" + getLocalName()); + break; + case XMLStreamConstants.END_ELEMENT: + logger.fine(getLocalName() + "]"); + break; + default: + String val = tagStrings.get(tag); + logger.fine((val == null) ? "Weird tag: " + tag : val); + break; + } } } return tag; @@ -524,7 +526,7 @@ public float getAttribute(String attributeName, float defaultValue) { try { result = Float.parseFloat(attrib); } catch (NumberFormatException e) { - logger.warning(attributeName + " is not a float: " + attrib); + if (logger.isLoggable(Level.WARNING)) logger.warning(attributeName + " is not a float: " + attrib); } } return result; @@ -545,7 +547,7 @@ public int getAttribute(String attributeName, int defaultValue) { try { result = Integer.decode(attrib); } catch (NumberFormatException e) { - logger.warning(attributeName + " is not an integer: " + attrib); + if (logger.isLoggable(Level.WARNING)) logger.warning(attributeName + " is not an integer: " + attrib); } } return result; @@ -566,7 +568,7 @@ public long getAttribute(String attributeName, long defaultValue) { try { result = Long.decode(attrib); } catch (NumberFormatException e) { - logger.warning(attributeName + " is not a long: " + attrib); + if (logger.isLoggable(Level.WARNING)) logger.warning(attributeName + " is not a long: " + attrib); } } return result; @@ -604,8 +606,8 @@ public > T getAttribute(String attributeName, if (attrib != null) { try { result = Enum.valueOf(returnClass, upCase(attrib)); - } catch (Exception e) { - logger.warning(attributeName + " is not a " + } catch (IllegalArgumentException e) { + if (logger.isLoggable(Level.WARNING)) logger.warning(attributeName + " is not a " + returnClass.getName() + ": " + attrib); } } @@ -693,7 +695,7 @@ public Location getLocationAttribute(Game game, String attributeName, } } if (fco instanceof Location) return (Location)fco; - logger.warning("Not a location: " + attrib); + if (logger.isLoggable(Level.WARNING)) logger.warning("Not a location: " + attrib); return null; } @@ -768,7 +770,9 @@ public List readList(Specification spec, List list = new ArrayList<>(length); for (int x = 0; x < length; x++) { T value = getType(spec, FreeColObject.arrayKey(x), type, (T)null); - if (value == null) logger.warning("Null list value(" + x + ")"); + if (value == null) { + if (logger.isLoggable(Level.WARNING)) logger.warning("Null list value(" + x + ")"); + } list.add(value); } @@ -840,22 +844,25 @@ public T makeFreeColObject(Game game, throw new XMLStreamException("Missing " + attributeName + " for " + returnClass.getName() + ": " + currentTag()); } - } else if ((ret = lookup(game, id, returnClass)) == null) { - ret = Game.newInstance(game, returnClass, - getReadScope() == ReadScope.SERVER); + } else { + ret = lookup(game, id, returnClass); if (ret == null) { - String err = "Failed to create " + returnClass.getName() - + " with id: " + id; - if (required) throw new XMLStreamException(err); - logger.warning(err); - } else if (ret instanceof FreeColGameObject) { - // Do not set the id earlier or interning will happen - // by default in the constructor called from newInstance - ret.setId(id); - if (shouldIntern()) { - ((FreeColGameObject)ret).internId(id); - } else { - uninterned.put(id, ret); + ret = Game.newInstance(game, returnClass, + getReadScope() == ReadScope.SERVER); + if (ret == null) { + String err = "Failed to create " + returnClass.getName() + + " with id: " + id; + if (required) throw new XMLStreamException(err); + logger.warning(err); + } else if (ret instanceof FreeColGameObject) { + // Do not set the id earlier or interning will happen + // by default in the constructor called from newInstance + ret.setId(id); + if (shouldIntern()) { + ((FreeColGameObject)ret).internId(id); + } else { + uninterned.put(id, ret); + } } } } @@ -1038,7 +1045,7 @@ public T makeAIObject(AIMain aiMain, if (required) { throw new XMLStreamException(e); } else { - logger.log(Level.WARNING, "Failed to create AIObject: " + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Failed to create AIObject: " + id, e); } } diff --git a/src/net/sf/freecol/common/io/FreeColXMLWriter.java b/src/net/sf/freecol/common/io/FreeColXMLWriter.java index f4ad8d639a..489495472c 100644 --- a/src/net/sf/freecol/common/io/FreeColXMLWriter.java +++ b/src/net/sf/freecol/common/io/FreeColXMLWriter.java @@ -113,6 +113,7 @@ public Player getClient() { return this.player; } + @Override public String toString() { String ret = this.scopeType.toString(); if (this.scopeType == WriteScopeType.CLIENT) { @@ -264,7 +265,7 @@ public StringBuffer flushBuffer() throws XMLStreamException { try { this.outputWriter.write(str); } catch (IOException ioe) { - logger.log(Level.WARNING, "Flush-write fail:" + str, ioe); + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Flush-write fail:" + str, ioe); } } else { StreamSource source = new StreamSource(new StringReader(str)); @@ -272,7 +273,7 @@ public StringBuffer flushBuffer() throws XMLStreamException { try { this.transformer.transform(source, result); } catch (TransformerException te) { - logger.log(Level.WARNING, "Transform fail:" + str, te); + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Transform fail:" + str, te); } } @@ -301,7 +302,9 @@ public void flush() throws XMLStreamException { public void close() { try { flush(); - } catch (XMLStreamException xse) {} // Ignore flush fail on close + } catch (XMLStreamException xse) { + logger.log(Level.FINE, "Flush failed on close.", xse); + } if (this.xmlStreamWriter != null) { try { diff --git a/src/net/sf/freecol/common/logging/DefaultHandler.java b/src/net/sf/freecol/common/logging/DefaultHandler.java index 87193f2f62..077988bc5f 100644 --- a/src/net/sf/freecol/common/logging/DefaultHandler.java +++ b/src/net/sf/freecol/common/logging/DefaultHandler.java @@ -19,8 +19,14 @@ package net.sf.freecol.common.logging; +import java.io.FileDescriptor; +import java.io.FileOutputStream; import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; import java.io.Writer; +import java.nio.charset.StandardCharsets; +import java.util.logging.ErrorManager; import java.util.logging.Handler; import java.util.logging.Level; import java.util.logging.LogRecord; @@ -37,11 +43,16 @@ */ public final class DefaultHandler extends Handler { + private static final PrintWriter STDERR = new PrintWriter( + new OutputStreamWriter(new FileOutputStream(FileDescriptor.err), + StandardCharsets.UTF_8), + true); + /** Lock for the writer. */ private final Object writerLock = new Object(); /** A writer to write log records with. */ - private Writer writer = null; + private Writer writer; /** Flag to enable console logging. */ private final boolean consoleLogging; @@ -88,7 +99,7 @@ public DefaultHandler(boolean consoleLogging, Writer writer) { this.writer.write(sb.toString()); } } catch (IOException ioe) { - ioe.printStackTrace(System.err); + reportError("Failed to write log header", ioe, ErrorManager.WRITE_FAILURE); } } @@ -103,7 +114,7 @@ public void close() { this.writer.close(); this.writer = null; } catch (IOException ioe) { - ioe.printStackTrace(System.err); + reportError("Failed to close log writer", ioe, ErrorManager.CLOSE_FAILURE); } } } @@ -119,7 +130,7 @@ public void flush() { try { this.writer.flush(); } catch (IOException ioe) { - ioe.printStackTrace(System.err); + reportError("Failed to flush log writer", ioe, ErrorManager.FLUSH_FAILURE); } } } @@ -141,7 +152,7 @@ public void publish(LogRecord record) { String str = getFormatter().format(record); if (consoleLogging && record.getLevel().intValue() >= Level.WARNING.intValue()) { - System.err.println(str); + STDERR.println(str); } synchronized (this.writerLock) { @@ -151,8 +162,7 @@ public void publish(LogRecord record) { // Because FreeCol is still in a very early stage. flush(); } catch (IOException ioe) { - System.err.println("Failed to write log record: " + str); - ioe.printStackTrace(System.err); + reportError("Failed to write log record: " + str, ioe, ErrorManager.WRITE_FAILURE); } } } diff --git a/src/net/sf/freecol/common/logging/TextFormatter.java b/src/net/sf/freecol/common/logging/TextFormatter.java index 0ec0b5e764..9179d707c0 100644 --- a/src/net/sf/freecol/common/logging/TextFormatter.java +++ b/src/net/sf/freecol/common/logging/TextFormatter.java @@ -21,6 +21,7 @@ import java.io.PrintWriter; import java.io.StringWriter; +import java.lang.reflect.Method; import java.util.Date; import java.util.logging.Formatter; import java.util.logging.LogRecord; @@ -51,7 +52,7 @@ public String format(LogRecord record) { .append("\n\t").append(record.getLevel().getName()) .append(": ").append(record.getMessage().replaceAll("\n", "\n\t")) .append("\n\t").append(new Date(record.getMillis())) - .append("\n\tThread: ").append(record.getThreadID()) + .append("\n\tThread: ").append(getThreadId(record)) .append('\n'); if (record.getThrown() != null) { StringWriter sw = new StringWriter(); @@ -65,4 +66,22 @@ public String format(LogRecord record) { return result.toString(); } + + private static long getThreadId(LogRecord record) { + try { + Method method = LogRecord.class.getMethod("getLongThreadID"); + Object value = method.invoke(record); + if (value instanceof Long) return (Long) value; + } catch (ReflectiveOperationException | SecurityException e) { + // Fall back to older API. + } + try { + Method method = LogRecord.class.getMethod("getThreadID"); + Object value = method.invoke(record); + if (value instanceof Integer) return ((Integer) value).longValue(); + } catch (ReflectiveOperationException | SecurityException e) { + return -1L; + } + return -1L; + } } diff --git a/src/net/sf/freecol/common/logging/package-info.java b/src/net/sf/freecol/common/logging/package-info.java index 0d7a0678af..d146bcc9da 100644 --- a/src/net/sf/freecol/common/logging/package-info.java +++ b/src/net/sf/freecol/common/logging/package-info.java @@ -1,5 +1,5 @@ /** - *

FreeCol Common Logging package

+ *

FreeCol Common Logging package

* *

Contains classes for handling logging information within FreeCol.

* diff --git a/src/net/sf/freecol/common/metaserver/MetaServerUtils.java b/src/net/sf/freecol/common/metaserver/MetaServerUtils.java index bfbd3d8d54..b56dfd6cde 100644 --- a/src/net/sf/freecol/common/metaserver/MetaServerUtils.java +++ b/src/net/sf/freecol/common/metaserver/MetaServerUtils.java @@ -98,7 +98,7 @@ public Message handle(Connection connection, Message message) this.consumer.accept(slm.getServers()); break; default: - logger.warning("MetaInputHandler does not handle: " + tag); + if (logger.isLoggable(Level.WARNING)) logger.warning("MetaInputHandler does not handle: " + tag); break; } return null; @@ -231,7 +231,7 @@ private static Connection getMetaServerConnection(List lsi) { c.startReceiving(); return c; } catch (IOException ioe) { - logger.log(Level.WARNING, "Could not connect to meta-server: " + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Could not connect to meta-server: " + host + ":" + port, ioe); } return null; @@ -267,11 +267,11 @@ private static boolean metaMessage(MetaMessageType type, ServerInfo si) { } return true; default: - logger.log(Level.WARNING, "Wrong metaMessage type: " + type); + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Wrong metaMessage type: " + type); break; } } catch (FreeColException|IOException|XMLStreamException|TimeoutException ex) { - logger.log(Level.WARNING, "Meta message " + type + " failure.", ex); + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Meta message " + type + " failure.", ex); // Do not fail: Try registering again later: return true; } diff --git a/src/net/sf/freecol/common/model/BaseProduction.java b/src/net/sf/freecol/common/model/BaseProduction.java index 03ef5acd56..68bc5982b9 100644 --- a/src/net/sf/freecol/common/model/BaseProduction.java +++ b/src/net/sf/freecol/common/model/BaseProduction.java @@ -28,6 +28,7 @@ * {@link #getBaseProduction(ProductionType, GoodsType, UnitType)} * method originally was identical methods in seperate classes */ +@FunctionalInterface public interface BaseProduction { /** diff --git a/src/net/sf/freecol/common/model/BuildQueue.java b/src/net/sf/freecol/common/model/BuildQueue.java index af7ea878ed..8148c3eaa4 100644 --- a/src/net/sf/freecol/common/model/BuildQueue.java +++ b/src/net/sf/freecol/common/model/BuildQueue.java @@ -65,10 +65,10 @@ public static enum CompletionAction { private final List queue = new ArrayList<>(); /** What to do when an item has been completed. */ - private CompletionAction completionAction = CompletionAction.REMOVE; + private CompletionAction completionAction; /** The build priority. */ - private int priority = COLONY_PRIORITY; + private int priority; /** The colony to queue buildables for. */ private final Colony colony; diff --git a/src/net/sf/freecol/common/model/Colony.java b/src/net/sf/freecol/common/model/Colony.java index 4a07284cb2..758dd6d47f 100644 --- a/src/net/sf/freecol/common/model/Colony.java +++ b/src/net/sf/freecol/common/model/Colony.java @@ -780,7 +780,9 @@ public T getWorkLocationWithAbility(String ability, WorkLocation wl = getWorkLocationWithAbility(ability); try { if (wl != null) return returnClass.cast(wl); - } catch (ClassCastException cce) {}; + } catch (ClassCastException cce) { + logger.log(Level.FINE, "Failed to cast work location.", cce); + } return null; } @@ -807,7 +809,13 @@ public WorkLocation getWorkLocationWithModifier(String modifier) { public T getWorkLocationWithModifier(String modifier, Class returnClass) { WorkLocation wl = getWorkLocationWithModifier(modifier); - if (wl != null) try { return returnClass.cast(wl); } catch (ClassCastException cce) {} + if (wl != null) { + try { + return returnClass.cast(wl); + } catch (ClassCastException cce) { + logger.log(Level.FINE, "Failed to cast work location.", cce); + } + } return null; } @@ -1358,12 +1366,12 @@ private int calculateProductionBonus(int solPercent) { */ protected boolean updateProductionBonus() { int newBonus = calculateProductionBonus(sonsOfLiberty); - if (productionBonus != newBonus) { + boolean changed = productionBonus != newBonus; + if (changed) { invalidateCache(); setProductionBonus(newBonus); - return true; } - return false; + return changed; } /** @@ -1467,7 +1475,7 @@ public boolean joinColony(Unit unit) { } if (!ret) { unit.setLocation(getTile()); // Fall back to safe value - logger.warning("Failed to join " + getName() + ": " + unit); + if (logger.isLoggable(Level.WARNING)) logger.warning("Failed to join " + getName() + ": " + unit); } return ret; } @@ -3122,12 +3130,14 @@ protected void writeAttributes(FreeColXMLWriter xw) throws XMLStreamException { if (uc > 0) { // Valid if above zero xw.writeAttribute(UNIT_COUNT_TAG, uc); } else if (uc == 0) { // Zero is an error! Find that bug - FreeCol.trace(logger, "Unit count fail: " + uc - + " id=" + getId() + " name=" + getName() - + " unitCount=" + getUnitCount() - + " displayUnitCount=" + this.displayUnitCount - + " scope=" + xw.getWriteScope() - + "/" + xw.getClientPlayer()); + if (logger.isLoggable(Level.WARNING)) { + logger.log(Level.WARNING, "Unit count fail: " + uc + + " id=" + getId() + " name=" + getName() + + " unitCount=" + getUnitCount() + + " displayUnitCount=" + this.displayUnitCount + + " scope=" + xw.getWriteScope() + + "/" + xw.getClientPlayer(), new Exception()); + } } // else do nothing, negative means no value set } } diff --git a/src/net/sf/freecol/common/model/Constants.java b/src/net/sf/freecol/common/model/Constants.java index 6f880625e9..dafa1a68ff 100644 --- a/src/net/sf/freecol/common/model/Constants.java +++ b/src/net/sf/freecol/common/model/Constants.java @@ -25,7 +25,9 @@ * Contains the constants. These constants are used by the * controllers and input handlers when they are communicating. */ -public interface Constants { +public final class Constants { + + private Constants() {} /** Generic "huge" value. */ public static final int INFINITY = Integer.MAX_VALUE; @@ -34,7 +36,7 @@ public interface Constants { public static final int UNDEFINED = Integer.MIN_VALUE; /** The result of checkIntegrity. */ - public static enum IntegrityType { + public enum IntegrityType { INTEGRITY_FAIL(-1), INTEGRITY_FIXED(0), INTEGRITY_GOOD(1); diff --git a/src/net/sf/freecol/common/model/Europe.java b/src/net/sf/freecol/common/model/Europe.java index f79a61c27c..68ecfe6ed0 100644 --- a/src/net/sf/freecol/common/model/Europe.java +++ b/src/net/sf/freecol/common/model/Europe.java @@ -238,11 +238,11 @@ private void setRecruitables(List recruitables) { * @return True if the recruitable was added. */ protected boolean addRecruitable(AbstractUnit au, boolean force) { - if (force || this.recruitables.size() < MigrationType.MIGRANT_COUNT) { - this.recruitables.add(au); - return true; + if (!force && this.recruitables.size() >= MigrationType.MIGRANT_COUNT) { + return false; } - return false; + this.recruitables.add(au); + return true; } /** diff --git a/src/net/sf/freecol/common/model/EuropeWas.java b/src/net/sf/freecol/common/model/EuropeWas.java index 0042f399bb..b5c1d77c99 100644 --- a/src/net/sf/freecol/common/model/EuropeWas.java +++ b/src/net/sf/freecol/common/model/EuropeWas.java @@ -66,10 +66,10 @@ public Unit getNewUnit() { */ public boolean fireChanges() { final int newCount = europe.getUnitCount(); - if (newCount != this.unitCount) { + boolean changed = newCount != this.unitCount; + if (changed) { europe.firePropertyChange(Europe.UNIT_CHANGE, unitCount, newCount); - return true; } - return false; + return changed; } } diff --git a/src/net/sf/freecol/common/model/EuropeanNationType.java b/src/net/sf/freecol/common/model/EuropeanNationType.java index c9c37bb97e..51c25e71ce 100644 --- a/src/net/sf/freecol/common/model/EuropeanNationType.java +++ b/src/net/sf/freecol/common/model/EuropeanNationType.java @@ -217,13 +217,15 @@ protected void writeChildren(FreeColXMLWriter xw) throws XMLStreamException { if (startingUnitMap != null && !startingUnitMap.isEmpty()) { Map map; // default map - if ((map = startingUnitMap.get(DEFAULT_MAP_KEY)) != null) { + map = startingUnitMap.get(DEFAULT_MAP_KEY); + if (map != null) { for (Map.Entry entry : map.entrySet()) { writeUnit(xw, entry.getKey(), entry.getValue(), false); } } // expert map - if ((map = startingUnitMap.get(EXPERT_MAP_KEY)) != null) { + map = startingUnitMap.get(EXPERT_MAP_KEY); + if (map != null) { for (Map.Entry entry : map.entrySet()) { writeUnit(xw, entry.getKey(), entry.getValue(), true); } diff --git a/src/net/sf/freecol/common/model/Force.java b/src/net/sf/freecol/common/model/Force.java index 36da1de80b..5ba38cb68a 100644 --- a/src/net/sf/freecol/common/model/Force.java +++ b/src/net/sf/freecol/common/model/Force.java @@ -28,6 +28,7 @@ import net.sf.freecol.common.io.FreeColXMLReader; import net.sf.freecol.common.io.FreeColXMLWriter; import static net.sf.freecol.common.util.CollectionUtils.*; +import java.util.logging.Level; /** @@ -77,7 +78,7 @@ public Force(Specification spec, List units, String ability) { if (ability == null || au.getType(spec).hasAbility(ability)) { add(au); } else { - logger.warning("Found unit lacking required ability \"" + if (logger.isLoggable(Level.WARNING)) logger.warning("Found unit lacking required ability \"" + ability + "\": " + au); } } @@ -324,7 +325,7 @@ public void readFromXML(FreeColXMLReader xr) throws XMLStreamException { add(new AbstractUnit(xr)); } } else { - logger.warning("Bogus Force tag: " + tag); + if (logger.isLoggable(Level.WARNING)) logger.warning("Bogus Force tag: " + tag); } } } diff --git a/src/net/sf/freecol/common/model/FreeColObject.java b/src/net/sf/freecol/common/model/FreeColObject.java index 6e988d9bdf..72e557e096 100644 --- a/src/net/sf/freecol/common/model/FreeColObject.java +++ b/src/net/sf/freecol/common/model/FreeColObject.java @@ -22,15 +22,19 @@ import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; +import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.OutputStream; +import java.io.PrintStream; import java.io.StringReader; import java.io.StringWriter; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.util.Collection; import java.util.Comparator; import java.util.List; +import java.lang.reflect.InvocationTargetException; import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Stream; @@ -65,6 +69,7 @@ public abstract class FreeColObject /** Comparator by FCO identifier. */ public static final Comparator fcoComparator = new Comparator() { + @Override public int compare(FreeColObject fco1, FreeColObject fco2) { return FreeColObject.compareIds(fco1, fco2); } @@ -100,7 +105,7 @@ public static Class getFreeColObjectClassByName(Str + capitalize(name); final Class c = (Class)Introspector.getClassByName(type); if (c != null) return c; - logger.warning("getFreeColObjectClass could not find: " + type); + if (logger.isLoggable(Level.WARNING)) logger.warning("getFreeColObjectClass could not find: " + type); return null; } @@ -212,7 +217,9 @@ public int getIdNumber() { // end @compat 0.11.6 try { return Integer.parseInt(s); - } catch (NumberFormatException nfe) {} + } catch (NumberFormatException nfe) { + if (logger.isLoggable(Level.FINE)) logger.log(Level.FINE, "Invalid id number: " + s, nfe); + } } } return -1; @@ -824,8 +831,9 @@ protected T invokeMethod(String methodName, Class returnClass, if (methodName != null && returnClass != null) { try { return Introspector.invokeMethod(this, methodName, returnClass); - } catch (Exception ex) { - logger.log(Level.WARNING, "Invoke failed: " + methodName, ex); + } catch (IllegalAccessException | InvocationTargetException + | NoSuchMethodException ex) { + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Invoke failed: " + methodName, ex); } } return defaultValue; @@ -863,7 +871,13 @@ public FreeColObject getDisplayObject() { * Debugging tool, dump object XML to System.err. */ public void dumpObject() { - save(System.err, WriteScope.toSave(), false); + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + try (PrintStream ps = new PrintStream(bos, true, StandardCharsets.UTF_8)) { + save(ps, WriteScope.toSave(), false); + } + if (logger.isLoggable(Level.FINE)) { + logger.fine(new String(bos.toByteArray(), StandardCharsets.UTF_8)); + } } /** @@ -1051,7 +1065,7 @@ public T copy(Game game, Class returnClass) { = new FreeColXMLReader(new StringReader(this.serialize()))) { ret = xr.copy(game, returnClass); } catch (XMLStreamException xse) { - logger.log(Level.WARNING, "Copy of " + getId() + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Copy of " + getId() + " to " + returnClass.getName() + "failed", xse); } return ret; @@ -1073,7 +1087,7 @@ public T copy(Game game, Class returnClass, = new FreeColXMLReader(new StringReader(this.serialize(player)))) { ret = xr.copy(game, returnClass); } catch (XMLStreamException xse) { - logger.log(Level.WARNING, "Copy of " + getId() + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Copy of " + getId() + " to " + returnClass.getName() + " for " + player.getId() + "failed", xse); } @@ -1111,12 +1125,14 @@ public boolean copyIn(T other) { copyInCast(T other, Class returnClass) { if (other == null) return (R)null; if (!idEquals(other)) { - logger.warning("copyInCast " + other.getId() + " onto " + getId()); + if (logger.isLoggable(Level.WARNING)) logger.warning("copyInCast " + other.getId() + " onto " + getId()); return (R)null; } try { return returnClass.cast(other); - } catch (ClassCastException cce) {} + } catch (ClassCastException cce) { + logger.log(Level.FINE, "Failed to cast copy target.", cce); + } return (R)null; } @@ -1172,7 +1188,7 @@ public void toXML(FreeColXMLWriter xw, String tag) throws XMLStreamException { */ protected void writeAttributes(FreeColXMLWriter xw) throws XMLStreamException { if (getId() == null) { - logger.warning("FreeColObject with null identifier: " + this); + if (logger.isLoggable(Level.WARNING)) logger.warning("FreeColObject with null identifier: " + this); } else { xw.writeAttribute(ID_ATTRIBUTE_TAG, getId()); } @@ -1207,7 +1223,7 @@ protected void writeChildren(FreeColXMLWriter xw) throws XMLStreamException { * to the stream. */ public final void toXMLPartial(FreeColXMLWriter xw, - String[] fields) throws XMLStreamException { + String... fields) throws XMLStreamException { final Class theClass = getClass(); xw.writeStartElement(getXMLTagName()); @@ -1222,7 +1238,7 @@ public final void toXMLPartial(FreeColXMLWriter xw, String value = intro.getter(this); xw.writeAttribute(field, value); } catch (Introspector.IntrospectorException ie) { - logger.log(Level.WARNING, "Failed to write field: " + field, ie); + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Failed to write field: " + field, ie); } } @@ -1256,8 +1272,8 @@ public final void toXMLPartial(FreeColXMLWriter xw, xw.writeEndElement(); - } catch (Exception e) { - logger.log(Level.WARNING, "Partial write failed for " + } catch (XMLStreamException e) { + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Partial write failed for " + theClass.getName(), e); } } @@ -1323,7 +1339,7 @@ protected void readChildren(FreeColXMLReader xr) throws XMLStreamException { readChild(xr); } } catch (XMLStreamException xse) { - logger.log(Level.SEVERE, "nextTag failed at " + tag, xse); + if (logger.isLoggable(Level.SEVERE)) logger.log(Level.SEVERE, "nextTag failed at " + tag, xse); } xr.expectTag(tag); } @@ -1372,8 +1388,8 @@ public final void readFromXMLPartial(FreeColXMLReader xr) throws XMLStreamExcept Introspector intro = new Introspector(theClass, name); intro.setter(this, xr.getAttributeValue(i)); - } catch (Exception e) { - logger.log(Level.WARNING, "Could not set field " + name, e); + } catch (Introspector.IntrospectorException e) { + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Could not set field " + name, e); } } diff --git a/src/net/sf/freecol/common/model/FreeColSpecObjectType.java b/src/net/sf/freecol/common/model/FreeColSpecObjectType.java index b6f887aadc..24bd5fc244 100644 --- a/src/net/sf/freecol/common/model/FreeColSpecObjectType.java +++ b/src/net/sf/freecol/common/model/FreeColSpecObjectType.java @@ -281,14 +281,6 @@ protected void clearContainers(FreeColXMLReader xr) throws XMLStreamException { ScopeContainer.clearScopes(this.scopeContainer); } - /** - * {@inheritDoc} - */ - @Override - protected void readChildren(FreeColXMLReader xr) throws XMLStreamException { - super.readChildren(xr); - } - /** * {@inheritDoc} */ diff --git a/src/net/sf/freecol/common/model/Game.java b/src/net/sf/freecol/common/model/Game.java index aefc670f88..b081cc6fb3 100644 --- a/src/net/sf/freecol/common/model/Game.java +++ b/src/net/sf/freecol/common/model/Game.java @@ -323,7 +323,7 @@ public static T newInstance(Game game, new Class[] { Specification.class }, new Object[] { game.getSpecification() }); } catch (Introspector.IntrospectorException ex) { - logger.log(Level.WARNING, "newInstance(spec) fail for: " + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "newInstance(spec) fail for: " + returnClass.getName(), ex); } } else { // Or just use the trivial constructor @@ -331,7 +331,7 @@ public static T newInstance(Game game, return Introspector.instantiate(returnClass, new Class[] {}, new Object[] {}); } catch (Introspector.IntrospectorException ex) { - logger.log(Level.WARNING, "newInstance(trivial) fail for: " + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "newInstance(trivial) fail for: " + returnClass.getName(), ex); } } @@ -490,7 +490,7 @@ public void removeFreeColGameObject(String id, String reason) { throw new RuntimeException("Null/empty identifier: " + this); } - logger.finest("removeFCGO/" + reason + ": " + id); + if (logger.isLoggable(Level.FINEST)) logger.finest("removeFCGO/" + reason + ": " + id); notifyRemoveFreeColGameObject(id); synchronized (this.freeColGameObjects) { this.freeColGameObjects.remove(id); @@ -541,7 +541,7 @@ private T update(T other, fcgo.setId(id); } else { // Otherwise this is an error - logger.warning("Update of missing object: " + id + if (logger.isLoggable(Level.WARNING)) logger.warning("Update of missing object: " + id + "\n" + net.sf.freecol.common.debug.FreeColDebugger.stackTraceToString()); return null; } @@ -715,7 +715,7 @@ public void remove() { final String key = this.readAhead.getKey(); this.fcgoState = FcgoState.INVALID; this.it.remove(); - logger.finest("removeFCGO/expire: " + key); + if (logger.isLoggable(Level.FINEST)) logger.finest("removeFCGO/expire: " + key); notifyRemoveFreeColGameObject(key); } }; @@ -995,20 +995,21 @@ public void addPlayers(List players) { for (Player p : players) { FreeColGameObject fcgo = getFreeColGameObject(p.getId()); if (fcgo == null) { - if ((fcgo = update(p, Player.class, true)) != null) { + fcgo = update(p, Player.class, true); + if (fcgo != null) { addPlayer((Player)fcgo); - logger.finest("addPlayers added new: " + fcgo); + if (logger.isLoggable(Level.FINEST)) logger.finest("addPlayers added new: " + fcgo); } else { - logger.warning("addPlayers create new fail: " + p); + if (logger.isLoggable(Level.WARNING)) logger.warning("addPlayers create new fail: " + p); } } else if (fcgo instanceof Player) { if (fcgo.copyIn(p)) { - logger.finest("addPlayers copied in: " + fcgo); + if (logger.isLoggable(Level.FINEST)) logger.finest("addPlayers copied in: " + fcgo); } else { - logger.warning("addPlayers copyIn existing fail: " + p); + if (logger.isLoggable(Level.WARNING)) logger.warning("addPlayers copyIn existing fail: " + p); } } else { - logger.warning("addPlayers onto non-player: " + fcgo); + if (logger.isLoggable(Level.WARNING)) logger.warning("addPlayers onto non-player: " + fcgo); } } } @@ -1408,7 +1409,7 @@ public FreeColObject getMessageDisplay(ModelMessage message) { if (o == null) { try { o = getSpecification().getType(id); - } catch (Exception e) { + } catch (IllegalArgumentException e) { o = null; // Ignore } } @@ -1483,7 +1484,9 @@ public T unserialize(String xml, ret.readFromXML(xr); return ret; - } catch (Exception ex) { + } catch (XMLStreamException ex) { + throw ex; + } catch (IllegalArgumentException ex) { throw new XMLStreamException(ex); } } @@ -1837,7 +1840,7 @@ protected void readChild(FreeColXMLReader xr) throws XMLStreamException { areas.put(area.getId(), area); } } catch (XMLStreamException xse) { - logger.log(Level.SEVERE, "nextTag failed at " + tag, xse); + if (logger.isLoggable(Level.SEVERE)) logger.log(Level.SEVERE, "nextTag failed at " + tag, xse); } } else { super.readChild(xr); diff --git a/src/net/sf/freecol/common/model/Goods.java b/src/net/sf/freecol/common/model/Goods.java index d8bbab56a0..114613522c 100644 --- a/src/net/sf/freecol/common/model/Goods.java +++ b/src/net/sf/freecol/common/model/Goods.java @@ -72,7 +72,8 @@ private Goods(Game game) { * @param game The enclosing {@code Game}. * @param id The identifier (ignored, type gives identifier here). */ - public Goods(Game game, @SuppressWarnings("unused") String id) { + @SuppressWarnings("PMD.UnusedFormalParameter") + public Goods(Game game, String id) { this(game); } diff --git a/src/net/sf/freecol/common/model/HighScore.java b/src/net/sf/freecol/common/model/HighScore.java index 4476f338c3..4a91507b88 100644 --- a/src/net/sf/freecol/common/model/HighScore.java +++ b/src/net/sf/freecol/common/model/HighScore.java @@ -423,7 +423,7 @@ public static List loadHighScores() { if (!hsf.exists()) { try { if (hsf.createNewFile()) { - logger.info("Created empty high score file: " + if (logger.isLoggable(Level.INFO)) logger.info("Created empty high score file: " + hsf.getPath()); saveHighScores(scores); } else { @@ -431,7 +431,7 @@ public static List loadHighScores() { } } catch (IOException ioe) { scores = null; - logger.log(Level.WARNING, "Unable to create high score file: " + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Unable to create high score file: " + hsf.getPath(), ioe); } return scores; @@ -588,7 +588,7 @@ public void readAttributes(FreeColXMLReader xr) throws XMLStreamException { try { long l = xr.getAttribute(DATE_TAG, -1L); if (l >= 0) date = new Date(l); - } catch (Exception e) { + } catch (IllegalArgumentException e) { logger.log(Level.WARNING, "Bad long date", e); } // @compat 0.11.0 @@ -599,7 +599,7 @@ public void readAttributes(FreeColXMLReader xr) throws XMLStreamException { if (f >= 0.0 && f < Long.MAX_VALUE) { date = new Date((long)f); } - } catch (Exception e) { + } catch (IllegalArgumentException e) { logger.log(Level.WARNING, "Bad float date", e); } } @@ -619,7 +619,7 @@ public void readAttributes(FreeColXMLReader xr) throws XMLStreamException { String str = xr.getAttribute(GAMEUUID_TAG, (String)null); try { gameUUID = UUID.fromString(str); - } catch (Exception e) { + } catch (IllegalArgumentException e) { gameUUID = nullUUID; } diff --git a/src/net/sf/freecol/common/model/HighSeas.java b/src/net/sf/freecol/common/model/HighSeas.java index b11eea50f2..f8344039cf 100644 --- a/src/net/sf/freecol/common/model/HighSeas.java +++ b/src/net/sf/freecol/common/model/HighSeas.java @@ -29,6 +29,7 @@ import net.sf.freecol.common.io.FreeColXMLWriter; import static net.sf.freecol.common.util.CollectionUtils.*; import static net.sf.freecol.common.util.StringUtils.*; +import java.util.logging.Level; /** @@ -104,7 +105,7 @@ public void addDestination(Location destination) { this.destinations.add(destination); } } else { - logger.warning("Tried to add null destination to " + getId()); + if (logger.isLoggable(Level.WARNING)) logger.warning("Tried to add null destination to " + getId()); } } diff --git a/src/net/sf/freecol/common/model/IndianSettlement.java b/src/net/sf/freecol/common/model/IndianSettlement.java index e797073589..d81dc2de33 100644 --- a/src/net/sf/freecol/common/model/IndianSettlement.java +++ b/src/net/sf/freecol/common/model/IndianSettlement.java @@ -57,6 +57,7 @@ import net.sf.freecol.common.model.Constants.IntegrityType; import net.sf.freecol.common.option.GameOptions; import net.sf.freecol.common.util.LogBuilder; +import java.util.logging.Level; /** @@ -468,7 +469,8 @@ public List getWantedGoodsLabel(int index, Player player) { StringTemplate lab = null, tip = null; GoodsType gt; if (hasVisited(player)) { - if ((gt = getWantedGoods(index)) != null) { + gt = getWantedGoods(index); + if (gt != null) { lab = StringTemplate.label("").add(Messages.nameKey(gt)); String sale = player.getLastSaleString(this, gt); if (sale != null) { @@ -581,12 +583,10 @@ private void setContactLevel(Player player, ContactLevel level) { * and player. */ public boolean setContacted(Player player) { - if (!hasContacted(player)) { - setContactLevel(player, ContactLevel.CONTACTED); - initializeAlarm(player); - return true; - } - return false; + if (hasContacted(player)) return false; + setContactLevel(player, ContactLevel.CONTACTED); + initializeAlarm(player); + return true; } /** @@ -609,12 +609,10 @@ public boolean hasVisited(Player player) { * by the player. */ public boolean setVisited(Player player) { - if (!hasVisited(player)) { - if (!hasContacted(player)) initializeAlarm(player); - setContactLevel(player, ContactLevel.VISITED); - return true; - } - return false; + if (hasVisited(player)) return false; + if (!hasContacted(player)) initializeAlarm(player); + setContactLevel(player, ContactLevel.VISITED); + return true; } /** @@ -637,12 +635,10 @@ public boolean hasScouted(Player player) { * by the player. */ public boolean setScouted(Player player) { - if (!hasScouted(player)) { - if (!hasContacted(player)) initializeAlarm(player); - setContactLevel(player, ContactLevel.SCOUTED); - return true; - } - return false; + if (hasScouted(player)) return false; + if (!hasContacted(player)) initializeAlarm(player); + setContactLevel(player, ContactLevel.SCOUTED); + return true; } /** @@ -854,7 +850,7 @@ public int getPriceToBuy(GoodsType type, int amount) { // Do not simplify with *=, we want the integer truncation. price = wantedBonus * price / wantedBase; - logger.finest("Full price(" + amount + " " + type + ")" + if (logger.isLoggable(Level.FINEST)) logger.finest("Full price(" + amount + " " + type + ")" + " -> " + price); return price; } @@ -964,7 +960,7 @@ private int getMilitaryGoodsPriceToBuy(GoodsType type, int amount) { int valued = Math.max(0, required - getGoodsCount(type)); int price = (valued > amount / 2) ? full * amount : valued * full + getNormalGoodsPriceToBuy(type, amount - valued); - logger.finest("Military price(" + amount + " " + type + ")" + if (logger.isLoggable(Level.FINEST)) logger.finest("Military price(" + amount + " " + type + ")" + " valued=" + valued + " -> " + price); return price; diff --git a/src/net/sf/freecol/common/model/LandMap.java b/src/net/sf/freecol/common/model/LandMap.java index 386f3d2922..b2c068a95d 100644 --- a/src/net/sf/freecol/common/model/LandMap.java +++ b/src/net/sf/freecol/common/model/LandMap.java @@ -29,6 +29,7 @@ import net.sf.freecol.common.option.OptionGroup; import static net.sf.freecol.common.util.CollectionUtils.*; import static net.sf.freecol.common.util.RandomUtils.*; +import java.util.logging.Level; /** @@ -105,7 +106,7 @@ public LandMap(OptionGroup mgo, RandomIntCache cache) { int minNumberOfTiles = mgo.getInteger(MapGeneratorOptions.LAND_MASS) * getWidth() * getHeight() / 100; int gen = mgo.getSelection(MapGeneratorOptions.LAND_GENERATOR_TYPE); - logger.info("Using land generator " + if (logger.isLoggable(Level.INFO)) logger.info("Using land generator " + mgo.getSelectionName(MapGeneratorOptions.LAND_GENERATOR_TYPE) + " to make " + width + "x" + height + " map" + " with distance-to-edge=" + distanceToEdge @@ -275,7 +276,6 @@ private void createClassicLandMap(int distanceToEdge, int minNumberOfTiles) { // find a free tile. Decrease necessary minimum over // time, so that this process will eventually succeed. if (failCounter > 100) { - failCounter = 0; minNumberOfTiles--; break; } diff --git a/src/net/sf/freecol/common/model/Map.java b/src/net/sf/freecol/common/model/Map.java index adce9d51bb..c6be91f14e 100644 --- a/src/net/sf/freecol/common/model/Map.java +++ b/src/net/sf/freecol/common/model/Map.java @@ -104,7 +104,8 @@ public static enum Layer { public static final class Position { /** The coordinates of the position. */ - public final int x, y; + public final int x; + public final int y; /** @@ -257,7 +258,8 @@ public String toString() { /** The width and height of the map. */ - private int width = -1, height = -1; + private int width = -1; + private int height = -1; /** * The tiles that this map contains, as a 2D array. This starts @@ -497,7 +499,8 @@ private boolean setTile(Tile tile, int x, int y) { */ private boolean updateTile(Tile tile) { if (tile == null) return false; - final int x = tile.getX(), y = tile.getY(); + final int x = tile.getX(); + final int y = tile.getY(); if (!isValid(x, y)) return false; Tile old = this.tileArray[x][y]; if (old == null) return setTile(tile, x, y); @@ -646,7 +649,7 @@ public void clearRegions() { * @return A map of the fixed regions. */ public java.util.Map getFixedRegions() { - HashMap result = new HashMap<>(); + java.util.Map result = new HashMap<>(); for (Region r : getRegions()) { String n = r.getKey(); if (n != null) result.put(n, r); @@ -821,7 +824,10 @@ public Tile getClosestTile(Tile tile, Collection tiles) { */ public Tile getRandomLandTile(Random random) { final int SLOSH = 10; - int x = 0, y = 0, width = getWidth(), height = getHeight(); + int x = 0; + int y = 0; + int width = getWidth(); + int height = getHeight(); if (width >= SLOSH) { width -= SLOSH; x += SLOSH/2; @@ -940,23 +946,27 @@ public void forSubMap(int x, int y, int w, int h, * @return A list of {@code Tile}s found (empty on error). */ public List subMap(int x, int y, int w, int h) { - if (x < 0) { - w += x; - x = 0; - } - if (y < 0) { - h += y; - y = 0; - } - final int width = getWidth(); - final int height = getHeight(); - if (w <= 0 || h <= 0 || x > width || y > height) + int startX = x; + int startY = y; + int width = w; + int height = h; + if (startX < 0) { + width += startX; + startX = 0; + } + if (startY < 0) { + height += startY; + startY = 0; + } + final int mapWidth = getWidth(); + final int mapHeight = getHeight(); + if (width <= 0 || height <= 0 || startX > mapWidth || startY > mapHeight) return Collections.emptyList(); - if (x+w > width) w = width - x; - if (y+h > height) h = height - y; + if (startX + width > mapWidth) width = mapWidth - startX; + if (startY + height > mapHeight) height = mapHeight - startY; List ret = new ArrayList<>(); - for (int yi = y; yi < y+h; yi++) { - for (int xi = x; xi < x+w; xi++) { + for (int yi = startY; yi < startY + height; yi++) { + for (int xi = startX; xi < startX + width; xi++) { ret.add(getTile(xi, yi)); } } @@ -989,7 +999,8 @@ private final class CircleIterator implements Iterator { /** The current index in the circle with the current radius: */ private int n; /** The current position in the circle. */ - private int x, y; + private int x; + private int y; /** @@ -1150,6 +1161,7 @@ public Iterator iterator() { /** * Simple interface to supply a heuristic to the A* routine. */ + @FunctionalInterface private interface SearchHeuristic { int getValue(Tile tile); } @@ -1176,19 +1188,20 @@ private SearchHeuristic getManhattenHeuristic(final Tile endTile) { * @return The actual end location. */ private Location findRealEnd(Unit unit, Location end) { + Location currentEnd = end; while (true) { - if (end == null) { + if (currentEnd == null) { throw new RuntimeException("Null end for: " + unit); - } else if (end instanceof Europe) { - return end; - } else if (end instanceof Map) { - end = unit.getFullEntryLocation(); - } else if (end.getTile() != null) { - return end.getTile(); + } else if (currentEnd instanceof Europe) { + return currentEnd; + } else if (currentEnd instanceof Map) { + currentEnd = unit.getFullEntryLocation(); + } else if (currentEnd.getTile() != null) { + return currentEnd.getTile(); } else if (unit != null) { return unit.resolveDestination(); } else { - throw new RuntimeException("Invalid end: " + end); + throw new RuntimeException("Invalid end: " + currentEnd); } } } @@ -1206,10 +1219,11 @@ private Location findRealEnd(Unit unit, Location end) { */ private PathNode getBestEntryPath(Unit unit, Tile tile, Unit carrier, CostDecider costDecider) { - if (costDecider == null) - costDecider = CostDeciders.avoidSettlementsAndBlockingUnits(); + CostDecider effectiveCostDecider = (costDecider == null) + ? CostDeciders.avoidSettlementsAndBlockingUnits() + : costDecider; return searchMap(unit, tile, GoalDeciders.getHighSeasGoalDecider(), - costDecider, INFINITY, carrier, null, null); + effectiveCostDecider, INFINITY, carrier, null, null); } /** @@ -1251,7 +1265,8 @@ private PathNode findMapPath(Unit unit, Tile start, Tile end, Unit carrier, : null; final GoalDecider gd = GoalDeciders.getLocationGoalDecider(end); final SearchHeuristic sh = getManhattenHeuristic(end); - Unit embarkTo, endUnit; + Unit embarkTo; + Unit endUnit; PathNode path; if (start.getContiguity() == end.getContiguity()) { @@ -1350,7 +1365,8 @@ public PathNode findPath(final Unit unit, final Location start, final Location end, final Unit carrier, CostDecider costDecider, LogBuilder lb) { - if (traceSearch) lb = new LogBuilder(1024); + LogBuilder logBuilder = lb; + if (traceSearch) logBuilder = new LogBuilder(1024); // Validate the arguments, reducing to either Europe or a Tile. final Location realEnd; @@ -1363,7 +1379,8 @@ public PathNode findPath(final Unit unit, // Get the unit that will be used for off-map travel. final Unit offMapUnit = (carrier != null) ? carrier : unit; - PathNode p, path; + PathNode p; + PathNode path; Tile tile; if (realEnd instanceof Tile && !((Tile)realEnd).isExplored()) { // Do not allow finding a path into unexplored territory, @@ -1378,7 +1395,7 @@ && isSameContiguity(t, start))) : null; path = (closest == null) ? null : this.findPath(unit, start, closest, carrier, - costDecider, lb); + costDecider, logBuilder); if (path != null) { PathNode last = path.getLastNode(); last.next = new PathNode((Tile)realEnd, 0, @@ -1396,44 +1413,46 @@ && isSameContiguity(t, start))) if (offMapUnit == null || !offMapUnit.getType().canMoveToHighSeas()) { path = null; - - // Find the best place to enter the map from Europe - } else if ((p = getBestEntryPath(unit, (Tile)realEnd, carrier, - costDecider)) == null) { - path = null; - - // Now search forward from there to get a path in the - // right order (path costs are not symmetric). There are - // "expected" failures when rivers block due to foreign - // ship movement. There are also other failures which we - // would like to log. Try to filter out the first case. - } else if ((path = findMapPath(unit, - (tile = p.getLastNode().getTile()), (Tile)realEnd, - carrier, costDecider, lb)) == null) { - if (!((Tile)realEnd).isOnRiver()) { - LogBuilder l2 = new LogBuilder(512); - l2.add("Fail in findPath(", unit, ", ", tile, - ", ", realEnd, ", ", carrier, ")\n"); - l2.addStackTrace(); - l2.add(p.fullPathToString()); - findMapPath(unit, tile, (Tile)realEnd, - carrier, costDecider, l2); - l2.log(logger, Level.WARNING); - } - path = null; - - // At the front of the path insert a node for the starting - // location in Europe, correcting for the turns to sail to - // the entry location. } else { - path.addTurns(offMapUnit.getSailTurns()); - path.previous = new PathNode(start, unit.getMovesLeft(), - 0, carrier != null, null, path); - path = path.previous; - if (carrier != null && unit.getLocation() != carrier) { - path.previous = new PathNode(start, unit.getMovesLeft(), - 0, false, null, path); - path = path.previous; + // Find the best place to enter the map from Europe + p = getBestEntryPath(unit, (Tile)realEnd, carrier, costDecider); + if (p == null) { + path = null; + } else { + // Now search forward from there to get a path in the + // right order (path costs are not symmetric). There are + // "expected" failures when rivers block due to foreign + // ship movement. There are also other failures which we + // would like to log. Try to filter out the first case. + tile = p.getLastNode().getTile(); + path = findMapPath(unit, tile, (Tile)realEnd, + carrier, costDecider, logBuilder); + if (path == null) { + if (!((Tile)realEnd).isOnRiver()) { + LogBuilder l2 = new LogBuilder(512); + l2.add("Fail in findPath(", unit, ", ", tile, + ", ", realEnd, ", ", carrier, ")\n"); + l2.addStackTrace(); + l2.add(p.fullPathToString()); + findMapPath(unit, tile, (Tile)realEnd, + carrier, costDecider, l2); + l2.log(logger, Level.WARNING); + } + path = null; + } else { + // At the front of the path insert a node for the starting + // location in Europe, correcting for the turns to sail to + // the entry location. + path.addTurns(offMapUnit.getSailTurns()); + path.previous = new PathNode(start, unit.getMovesLeft(), + 0, carrier != null, null, path); + path = path.previous; + if (carrier != null && unit.getLocation() != carrier) { + path.previous = new PathNode(start, unit.getMovesLeft(), + 0, false, null, path); + path = path.previous; + } + } } } @@ -1443,19 +1462,20 @@ && isSameContiguity(t, start))) if (offMapUnit == null || !offMapUnit.getType().canMoveToHighSeas()) { path = null; - - // Search forwards to the high seas. - } else if ((p = searchMap(unit, (Tile)start, - GoalDeciders.getHighSeasGoalDecider(), - costDecider, INFINITY, carrier, null, lb)) == null) { - path = null; - } else { - PathNode last = p.getLastNode(); - last.next = new PathNode(realEnd, unit.getInitialMovesLeft(), - last.getTurns() + offMapUnit.getSailTurns(), - last.isOnCarrier(), last, null); - path = p; + // Search forwards to the high seas. + p = searchMap(unit, (Tile)start, + GoalDeciders.getHighSeasGoalDecider(), + costDecider, INFINITY, carrier, null, logBuilder); + if (p == null) { + path = null; + } else { + PathNode last = p.getLastNode(); + last.next = new PathNode(realEnd, unit.getInitialMovesLeft(), + last.getTurns() + offMapUnit.getSailTurns(), + last.isOnCarrier(), last, null); + path = p; + } } } else if (start instanceof Tile && realEnd instanceof Tile) { @@ -1475,14 +1495,14 @@ && isSameContiguity(t, start))) 0, false, path, null); } else { path = findMapPath(unit, (Tile)start, (Tile)realEnd, - carrier, costDecider, lb); + carrier, costDecider, logBuilder); } } else { throw new IllegalStateException("Can not happen: " + start + ", " + realEnd); } - finishPath(path, unit, lb); + finishPath(path, unit, logBuilder); return path; } @@ -1513,39 +1533,41 @@ public PathNode search(final Unit unit, Location start, final CostDecider costDecider, final int maxTurns, final Unit carrier, LogBuilder lb) { - if (traceSearch) lb = new LogBuilder(1024); + LogBuilder logBuilder = lb; + if (traceSearch) logBuilder = new LogBuilder(1024); final Unit offMapUnit = (carrier != null) ? carrier : unit; - PathNode p, path; + PathNode p; + PathNode path; if (start instanceof Europe) { // Fail fast if Europe is unattainable. if (offMapUnit == null || !offMapUnit.getType().canMoveToHighSeas()) { path = null; - + } else { // This is suboptimal. We do not know where to enter from // Europe, so start with the standard entry location... - } else if ((p = searchMap(unit, - offMapUnit.getFullEntryLocation(), - goalDecider, costDecider, maxTurns, carrier, - null, lb)) == null) { - path = null; - - // ...then if we find a path, try to optimize it. This - // will lose if the initial search fails due to a turn limit. - // FIXME: do something better. - } else { - path = this.findPath(unit, start, p.getLastNode().getTile(), - carrier, costDecider, lb); + p = searchMap(unit, offMapUnit.getFullEntryLocation(), + goalDecider, costDecider, maxTurns, carrier, + null, logBuilder); + if (p == null) { + path = null; + } else { + // ...then if we find a path, try to optimize it. This + // will lose if the initial search fails due to a turn limit. + // FIXME: do something better. + path = this.findPath(unit, start, p.getLastNode().getTile(), + carrier, costDecider, logBuilder); + } } } else { path = searchMap(unit, start.getTile(), goalDecider, - costDecider, maxTurns, carrier, null, lb); + costDecider, maxTurns, carrier, null, logBuilder); } - finishPath(path, unit, lb); + finishPath(path, unit, logBuilder); return path; } @@ -1581,11 +1603,14 @@ public boolean setSearchTrace(boolean trace) { * @return True if the path includes a previous on-carrier node. */ private boolean usedCarrier(PathNode path) { - while (path != null) { - if (path.isOnCarrier()) return true; - path = path.previous; + boolean used = false; + for (PathNode current = path; current != null; current = current.previous) { + if (current.isOnCarrier()) { + used = true; + break; + } } - return false; + return used; } /** @@ -1620,7 +1645,6 @@ public MoveCandidate(Unit unit, PathNode current, Location dst, this.unit = unit; this.current = current; this.dst = dst; - this.movesLeft = movesLeft; this.turns = turns; this.onCarrier = onCarrier; CostDecider cd = (decider != null) ? decider @@ -1692,9 +1716,9 @@ public boolean canImprove(PathNode best) { * @param f The heuristic values for A*. * @param sh A {@code SearchHeuristic} to apply. */ - public void improve(HashMap openMap, - PriorityQueue openMapQueue, - HashMap f, + public void improve(java.util.Map openMap, + Queue openMapQueue, + java.util.Map f, SearchHeuristic sh) { PathNode best = openMap.get(dst.getId()); if (best != null) { @@ -1712,9 +1736,9 @@ public void improve(HashMap openMap, * @param f The map of f-values. * @param sh A {@code SearchHeuristic} to apply. */ - public void add(HashMap openMap, - PriorityQueue openMapQueue, - HashMap f, + public void add(java.util.Map openMap, + Queue openMapQueue, + java.util.Map f, SearchHeuristic sh) { int fcost = this.cost; if (this.dst.getTile() != null) { @@ -1787,10 +1811,10 @@ private PathNode searchMap(final Unit unit, final Tile start, final int maxTurns, final Unit carrier, final SearchHeuristic searchHeuristic, final LogBuilder lb) { - final HashMap openMap = new HashMap<>(); - final HashMap closedMap = new HashMap<>(); - final HashMap f = new HashMap<>(); - final PriorityQueue openMapQueue = new PriorityQueue<>(1024, + final java.util.Map openMap = new HashMap<>(); + final java.util.Map closedMap = new HashMap<>(); + final java.util.Map f = new HashMap<>(); + final Queue openMapQueue = new PriorityQueue<>(1024, Comparator.comparingInt(p -> f.get(p.getLocation().getId()))); final SearchHeuristic sh = (searchHeuristic == null) ? trivialSearchHeuristic : searchHeuristic; @@ -1815,7 +1839,7 @@ private PathNode searchMap(final Unit unit, final Tile start, openMap.put(start.getId(), firstNode); openMapQueue.offer(firstNode); - PathNode best = null; + PathNode best; int bestScore = INFINITY; ok: while (!openMap.isEmpty()) { // Choose the node with the lowest f. @@ -1897,8 +1921,8 @@ private PathNode searchMap(final Unit unit, final Tile start, && carrier.getSimpleMoveType(carrier.getTile(), moveTile).isProgress(); if (lb != null) lb.add(" ", ((unitMove) ? "U" : ((carrierMove) ? "C" : ""))); - MoveCandidate move; - String stepLog; + MoveCandidate move = null; + String stepLog = ""; // Is this move to the goal? Use fake high cost so // this does not become cached inside the goal decider @@ -1944,13 +1968,11 @@ private PathNode searchMap(final Unit unit, final Tile start, move = new MoveCandidate(unit, currentNode, moveTile, currentMovesLeft, currentTurns, false, CostDeciders.tileCost()); - unitMove = true; break; case EMBARK: move = new MoveCandidate(unit, currentNode, moveTile, currentMovesLeft, currentTurns, true, CostDeciders.tileCost()); - unitMove = true; break; case MOVE_NO_ATTACK_CIVILIAN: // There is a settlement in the way, this @@ -1972,7 +1994,6 @@ private PathNode searchMap(final Unit unit, final Tile start, continue; } if (lb != null) lb.add(" blocked"); - unitMove = true; move = new MoveCandidate(unit, currentNode, moveTile, currentMovesLeft, currentTurns, false, CostDeciders.tileCost()); @@ -2049,12 +2070,15 @@ private PathNode searchMap(final Unit unit, final Tile start, move = new MoveCandidate(unit, currentNode, moveTile, 0, currentTurns, false, costDecider); break; - case FAIL: default: // Loop on failure. + case FAIL: // Loop on failure. if (lb != null) lb.add("!"); continue; } stepLog = " " + step + "_"; } + if (move == null) { + continue; + } if (move.cost >= INFINITY) { continue; } @@ -2164,17 +2188,20 @@ public static boolean[][] floodFillBool(boolean[][] boolmap, int x, int y) { */ public static boolean[][] floodFillBool(boolean[][] boolmap, int x, int y, int limit) { - final int xmax = boolmap.length, ymax = boolmap[0].length; + final int xmax = boolmap.length; + final int ymax = boolmap[0].length; boolean[][] visited = new boolean[xmax][ymax]; Queue q = new LinkedList<>(); visited[x][y] = true; Position p = new Position(x, y); - for (; p != null && --limit > 0; p = q.poll()) { + int remaining = limit; + for (; p != null && --remaining > 0; p = q.poll()) { for (Direction d : Direction.values()) { final Position np = new Position(p, d); if (!np.isValid(xmax, ymax)) continue; - int nx = np.getX(), ny = np.getY(); + int nx = np.getX(); + int ny = np.getY(); if (boolmap[nx][ny] && !visited[nx][ny]) { visited[nx][ny] = true; q.add(np); @@ -2191,7 +2218,8 @@ public static boolean[][] floodFillBool(boolean[][] boolmap, int x, int y, public void resetContiguity() { // Create the water map. It is an error for any tile not to // have a region at this point. - final int xmax = getWidth(), ymax = getHeight(); + final int xmax = getWidth(); + final int ymax = getHeight(); boolean[][] waterMap = new boolean[xmax][ymax]; for (int y = 0; y < ymax; y++) { for (int x = 0; x < xmax; x++) { @@ -2227,7 +2255,8 @@ public void resetContiguity() { * @param xmax The X-value * @param waterMap The boolean array containing the x and y coordinates */ - private void floodFill(int contig, int ymax, int xmax, boolean[][] waterMap) { + private void floodFill(int contig, int ymax, int xmax, boolean[]... waterMap) { + int contiguity = contig; for (int y = 0; y < ymax; y++) { for (int x = 0; x < xmax; x++) { if (waterMap[x][y]) { @@ -2240,12 +2269,12 @@ private void floodFill(int contig, int ymax, int xmax, boolean[][] waterMap) { if (found[xx][yy]) { Tile t = getTile(xx, yy); if (t.getContiguity() < 0) { - t.setContiguity(contig); + t.setContiguity(contiguity); } } } } - contig++; + contiguity++; } } } @@ -2323,9 +2352,15 @@ public void resetHighSeas(int distToLandFromHighSeas, // Reset all highSeas tiles to the default ocean type. forEachTile(t -> t.getType() == highSeas, t -> t.setType(ocean)); - final int width = getWidth(), height = getHeight(); - Tile t, seaL = null, seaR = null; - int totalL = 0, totalR = 0, distanceL = -1, distanceR = -1; + final int width = getWidth(); + final int height = getHeight(); + Tile t; + Tile seaL = null; + Tile seaR = null; + int totalL = 0; + int totalR = 0; + int distanceL = -1; + int distanceR = -1; for (int y = 0; y < height; y++) { for (int x = 0; x < maxDistanceToEdge && x < width && isValid(x, y) @@ -2369,7 +2404,7 @@ && isValid(width-1-x, y) totalR++; } if (totalL <= 0 || totalR <= 0) { - logger.warning("No high seas on " + if (logger.isLoggable(Level.WARNING)) logger.warning("No high seas on " + ((totalL <= 0 && totalR <= 0) ? "either" : (totalL <= 0) ? "left" : (totalR <= 0) ? "right" @@ -2441,12 +2476,13 @@ public void resetHighSeasCount() { * Reset layer to reflect what is actually there. */ public void resetLayers() { - boolean regions = false, - rivers = false, - lostCityRumours = false, - resources = false, - nativeSettlements = false; - final int hgt = getHeight(), wid = getWidth(); + boolean regions = false; + boolean rivers = false; + boolean lostCityRumours = false; + boolean resources = false; + boolean nativeSettlements = false; + final int hgt = getHeight(); + final int wid = getWidth(); for (int y = 0; y < hgt; y++) { for (int x = 0; x < wid; x++) { Tile t = getTile(x, y); @@ -2717,7 +2753,8 @@ public String getLocationImageKey() { @Override public IntegrityType checkIntegrity(boolean fix, LogBuilder lb) { IntegrityType result = super.checkIntegrity(fix, lb); - final int hgt = getHeight(), wid = getWidth(); + final int hgt = getHeight(); + final int wid = getWidth(); for (int y = 0; y < hgt; y++) { for (int x = 0; x < wid; x++) { Tile t = getTile(x, y); @@ -2791,7 +2828,8 @@ protected void writeChildren(FreeColXMLWriter xw) throws XMLStreamException { for (Region region : sort(getRegions())) region.toXML(xw); - final int hgt = getHeight(), wid = getWidth(); + final int hgt = getHeight(); + final int wid = getWidth(); for (int y = 0; y < hgt; y++) { for (int x = 0; x < wid; x++) { getTile(x, y).toXML(xw); @@ -2855,7 +2893,7 @@ protected void readChild(FreeColXMLReader xr) throws XMLStreamException { } else if (Tile.TAG.equals(tag)) { Tile t = xr.readFreeColObject(game, Tile.class); if (!updateTile(t)) { - logger.warning("Tile update failure for: " + t); + if (logger.isLoggable(Level.WARNING)) logger.warning("Tile update failure for: " + t); } } else { diff --git a/src/net/sf/freecol/common/model/MarketData.java b/src/net/sf/freecol/common/model/MarketData.java index 50ce4570dd..6e48f1a128 100644 --- a/src/net/sf/freecol/common/model/MarketData.java +++ b/src/net/sf/freecol/common/model/MarketData.java @@ -25,6 +25,7 @@ import net.sf.freecol.common.io.FreeColXMLReader; import net.sf.freecol.common.io.FreeColXMLWriter; +import java.util.logging.Level; /** @@ -346,7 +347,7 @@ public boolean price() { amountPrice -= newPrice - (costToBuy + diff); amountInMarket = Math.round(goodsType.getInitialAmount() * (initialPrice / amountPrice)); - logger.info("Clamped price rise for " + getId() + if (logger.isLoggable(Level.INFO)) logger.info("Clamped price rise for " + getId() + " from " + newPrice + " to " + (costToBuy + diff)); newPrice = costToBuy + diff; @@ -354,7 +355,7 @@ public boolean price() { amountPrice += (costToBuy - diff) - newPrice; amountInMarket = Math.round(goodsType.getInitialAmount() * (initialPrice / amountPrice)); - logger.info("Clamped price fall for " + getId() + if (logger.isLoggable(Level.INFO)) logger.info("Clamped price fall for " + getId() + " from " + newPrice + " to " + (costToBuy - diff)); newPrice = costToBuy - diff; diff --git a/src/net/sf/freecol/common/model/Monarch.java b/src/net/sf/freecol/common/model/Monarch.java index cb35fcd73e..d1a77a8b32 100644 --- a/src/net/sf/freecol/common/model/Monarch.java +++ b/src/net/sf/freecol/common/model/Monarch.java @@ -40,6 +40,7 @@ import net.sf.freecol.common.model.Player.PlayerType; import net.sf.freecol.common.option.GameOptions; import net.sf.freecol.common.util.RandomChoice; +import java.util.logging.Level; /** @@ -558,7 +559,7 @@ public AbstractUnit addToREF(Random random) { Force ref = getExpeditionaryForce(); ref.add(result); - logger.info("Add to " + player.getDebugName() + if (logger.isLoggable(Level.INFO)) logger.info("Add to " + player.getDebugName() + " REF: capacity=" + ref.getCapacity() + " spaceRequired=" + ref.getSpaceRequired() + " => " + result); @@ -713,7 +714,7 @@ public List getWarSupport(Player enemy, Random random) { } strength = AbstractUnit.calculateStrength(spec, result); ratio = Player.strengthRatio(baseStrength+strength, enemyStrength); - logger.finest("War support:" + if (logger.isLoggable(Level.FINEST)) logger.finest("War support:" + " initially=" + supportStrength + "/" + fullRatio + " finally=" + strength + "/" + ratio); } @@ -741,7 +742,7 @@ public int loadMercenaries(Random random, List mercs) { // FIXME: magic numbers for 2-4 mercs int count = randomInt(logger, "Mercenary count", random, 2) + 2; int price = 0; - UnitType unitType = null; + UnitType unitType; List unitTypes = new ArrayList<>(mercenaryTypes); while (count > 0 && !unitTypes.isEmpty()) { unitType = getRandomMember(logger, "Merc unit", diff --git a/src/net/sf/freecol/common/model/Named.java b/src/net/sf/freecol/common/model/Named.java index 0486d48895..7ce45becbf 100644 --- a/src/net/sf/freecol/common/model/Named.java +++ b/src/net/sf/freecol/common/model/Named.java @@ -23,6 +23,7 @@ /** * An object that has a name. */ +@FunctionalInterface public interface Named { /** diff --git a/src/net/sf/freecol/common/model/NativeTrade.java b/src/net/sf/freecol/common/model/NativeTrade.java index 8ab156d262..712bbdca24 100644 --- a/src/net/sf/freecol/common/model/NativeTrade.java +++ b/src/net/sf/freecol/common/model/NativeTrade.java @@ -29,6 +29,7 @@ import net.sf.freecol.common.io.FreeColXMLReader; import net.sf.freecol.common.io.FreeColXMLWriter; import static net.sf.freecol.common.util.CollectionUtils.*; +import java.util.logging.Level; /** @@ -612,7 +613,7 @@ protected void readChild(FreeColXMLReader xr) throws XMLStreamException { if (NativeTradeItem.TAG.equals(tag)) { this.settlementToUnit.add(new NativeTradeItem(game, xr)); } else { - logger.warning("SettlementToUnit-item expected, not: " + tag); + if (logger.isLoggable(Level.WARNING)) logger.warning("SettlementToUnit-item expected, not: " + tag); } } @@ -622,7 +623,7 @@ protected void readChild(FreeColXMLReader xr) throws XMLStreamException { if (NativeTradeItem.TAG.equals(tag)) { this.unitToSettlement.add(new NativeTradeItem(game, xr)); } else { - logger.warning("UnitToSettlement-item expected, not: " + tag); + if (logger.isLoggable(Level.WARNING)) logger.warning("UnitToSettlement-item expected, not: " + tag); } } diff --git a/src/net/sf/freecol/common/model/PathNode.java b/src/net/sf/freecol/common/model/PathNode.java index 77c0ec978c..0ef0c05a0e 100644 --- a/src/net/sf/freecol/common/model/PathNode.java +++ b/src/net/sf/freecol/common/model/PathNode.java @@ -52,13 +52,13 @@ public class PathNode { private int turns; /** Whether the unit traversing this path is on a carrier at this node. */ - private boolean onCarrier = false; + private boolean onCarrier; /** The next node in the path. */ - public PathNode next = null; + public PathNode next; /** The previous node in the path. */ - public PathNode previous = null; + public PathNode previous; /** @@ -320,11 +320,15 @@ public boolean usesCarrier() { * @return True if there was a non-carrier move in the last turn. */ public boolean embarkedThisTurn(int turns) { + boolean found = false; for (PathNode p = this; p != null; p = p.previous) { - if (p.getTurns() < turns) return false; - if (!p.isOnCarrier()) return true; + if (p.getTurns() < turns) break; + if (!p.isOnCarrier()) { + found = true; + break; + } } - return false; + return found; } /** diff --git a/src/net/sf/freecol/common/model/Player.java b/src/net/sf/freecol/common/model/Player.java index 07c8455bf7..72151b1d0e 100644 --- a/src/net/sf/freecol/common/model/Player.java +++ b/src/net/sf/freecol/common/model/Player.java @@ -73,6 +73,7 @@ import net.sf.freecol.common.option.OptionGroup; import net.sf.freecol.common.util.LogBuilder; import net.sf.freecol.common.util.Utils; +import java.util.logging.Level; /** @@ -648,7 +649,7 @@ public Connection getConnection() { * @param connection The {@code Connection}. */ public void setConnection(Connection connection) { - throw new RuntimeException("setConnection called on Player: " + this); + throw new IllegalStateException("setConnection called on Player: " + this); } /** @@ -658,7 +659,7 @@ public void setConnection(Connection connection) { * @return True if the message was sent. */ public boolean send(ChangeSet cs) { - throw new RuntimeException("send called on Player: " + this); + throw new IllegalStateException("send called on Player: " + this); } @@ -672,7 +673,7 @@ public boolean send(ChangeSet cs) { * @return A new {@code ChangeSet}. */ public ChangeSet clientError(StringTemplate template) { - logger.warning(Messages.message(template)); + if (logger.isLoggable(Level.WARNING)) logger.warning(Messages.message(template)); if (FreeColDebugger.isInDebugMode(FreeColDebugger.DebugMode.COMMS)) { Thread.dumpStack(); } @@ -1162,7 +1163,7 @@ public int modifyGold(int amount) { // where the balance is unknown. Just keep going and // do the best thing possible, we don't want to crash // the game here. - logger.warning("Cannot add " + amount + " gold for " + if (logger.isLoggable(Level.WARNING)) logger.warning("Cannot add " + amount + " gold for " + this + ": would be negative!"); gold = 0; } @@ -1278,7 +1279,7 @@ public void updateImmigrationRequired() { / apply(1f, turn, Modifier.RELIGIOUS_UNREST_BONUS)); immigrationRequired = (int)apply(unreduced + base, turn, Modifier.RELIGIOUS_UNREST_BONUS);; - logger.finest("Immigration for " + getId() + " updated " + current + if (logger.isLoggable(Level.FINEST)) logger.finest("Immigration for " + getId() + " updated " + current + " -> " + immigrationRequired); } @@ -2260,8 +2261,8 @@ public final TradeRoute getNewestTradeRoute() { * @param tradeRoute The {@code TradeRoute} to add. */ public final void addTradeRoute(TradeRoute tradeRoute) { - String name; - if (tradeRoute != null && (name = tradeRoute.getName()) != null + String name = (tradeRoute == null) ? null : tradeRoute.getName(); + if (tradeRoute != null && name != null && getTradeRouteByName(name, tradeRoute) == null) { synchronized (this.tradeRoutes) { this.tradeRoutes.add(tradeRoute); @@ -3981,7 +3982,7 @@ public int getColonyValue(Tile tile) { * @param what A description of the cheating. */ public void logCheat(String what) { - logger.finest("CHEAT: " + getGame().getTurn().getNumber() + if (logger.isLoggable(Level.FINEST)) logger.finest("CHEAT: " + getGame().getTurn().getNumber() + " " + lastPart(getNationId(), ".") + " " + what); } @@ -4029,7 +4030,7 @@ public T getOurFreeColGameObject(String id, T t = getGame().getFreeColGameObject(id, returnClass); if (t == null) { FreeColGameObject fcgo = getGame().getFreeColGameObject(id); - throw new RuntimeException("Not a " + returnClass.getName() + throw new IllegalArgumentException("Not a " + returnClass.getName() + ": " + id + "/" + fcgo); } else if (t instanceof Ownable) { if (!owns((Ownable)t)) { @@ -4037,7 +4038,7 @@ public T getOurFreeColGameObject(String id, + " not owned by " + getId() + ": " + id + "/" + t); } } else { - throw new RuntimeException("Not ownable: " + id + "/" + t); + throw new IllegalStateException("Not ownable: " + id + "/" + t); } return t; } diff --git a/src/net/sf/freecol/common/model/ProductionType.java b/src/net/sf/freecol/common/model/ProductionType.java index 734202cdd7..a16c8fdd52 100644 --- a/src/net/sf/freecol/common/model/ProductionType.java +++ b/src/net/sf/freecol/common/model/ProductionType.java @@ -33,6 +33,7 @@ import net.sf.freecol.common.io.FreeColXMLWriter; import static net.sf.freecol.common.util.CollectionUtils.*; import net.sf.freecol.common.util.Utils; +import java.util.logging.Level; /** @@ -482,7 +483,7 @@ public void readChild(FreeColXMLReader xr) throws XMLStreamException { GoodsType type = xr.getType(spec, GOODS_TYPE_TAG, GoodsType.class, (GoodsType)null); if (type == null) { - logger.warning("Skipping input with null type: " + if (logger.isLoggable(Level.WARNING)) logger.warning("Skipping input with null type: " + xr.getAttribute(GOODS_TYPE_TAG, (String)null)); } else { addInput(type, xr.getAttribute(VALUE_TAG, -1)); @@ -493,7 +494,7 @@ public void readChild(FreeColXMLReader xr) throws XMLStreamException { GoodsType type = xr.getType(spec, GOODS_TYPE_TAG, GoodsType.class, (GoodsType)null); if (type == null) { - logger.warning("Skipping output with null type: " + if (logger.isLoggable(Level.WARNING)) logger.warning("Skipping output with null type: " + xr.getAttribute(GOODS_TYPE_TAG, (String)null)); } else { addOutput(type, xr.getAttribute(VALUE_TAG, -1)); diff --git a/src/net/sf/freecol/common/model/RandomRange.java b/src/net/sf/freecol/common/model/RandomRange.java index 714b56914c..153b2970d4 100644 --- a/src/net/sf/freecol/common/model/RandomRange.java +++ b/src/net/sf/freecol/common/model/RandomRange.java @@ -90,7 +90,7 @@ public RandomRange(FreeColXMLReader xr) throws XMLStreamException { * * @return The probability. */ - public final int getProbability() { + public int getProbability() { return probability; } @@ -99,7 +99,7 @@ public final int getProbability() { * * @return The lower bound. */ - public final int getMinimum() { + public int getMinimum() { return minimum; } @@ -108,7 +108,7 @@ public final int getMinimum() { * * @return The upper bound. */ - public final int getMaximum() { + public int getMaximum() { return maximum; } @@ -117,7 +117,7 @@ public final int getMaximum() { * * @return The factor. */ - public final int getFactor() { + public int getFactor() { return factor; } diff --git a/src/net/sf/freecol/common/model/Resource.java b/src/net/sf/freecol/common/model/Resource.java index 98a895095c..02c7c13b89 100644 --- a/src/net/sf/freecol/common/model/Resource.java +++ b/src/net/sf/freecol/common/model/Resource.java @@ -29,6 +29,7 @@ import static net.sf.freecol.common.model.Constants.*; import net.sf.freecol.common.model.Map.Layer; import net.sf.freecol.common.util.LogBuilder; +import java.util.logging.Level; /** @@ -166,12 +167,12 @@ public int useQuantity(GoodsType goodsType, UnitType unitType, */ private int useQuantity(int usedQuantity) { if (quantity == UNLIMITED) { - ; // No change + return quantity; } else if (quantity >= usedQuantity) { quantity -= usedQuantity; } else { // Shouldn't generally happen. Do something more drastic here? - logger.severe("Insufficient quantity in " + this); + if (logger.isLoggable(Level.SEVERE)) logger.severe("Insufficient quantity in " + this); quantity = 0; } return quantity; diff --git a/src/net/sf/freecol/common/model/ScopeContainer.java b/src/net/sf/freecol/common/model/ScopeContainer.java index 41a958a2ed..767b552dba 100644 --- a/src/net/sf/freecol/common/model/ScopeContainer.java +++ b/src/net/sf/freecol/common/model/ScopeContainer.java @@ -44,6 +44,7 @@ public class ScopeContainer { /** Cached standard scope comparator. */ private static final Comparator scopeComparator = new Comparator() { + @Override public int compare(Scope s1, Scope s2) { return Long.compare(s1.hashCode(), s2.hashCode()); } diff --git a/src/net/sf/freecol/common/model/Specification.java b/src/net/sf/freecol/common/model/Specification.java index 6c83259aea..42122f3e2d 100644 --- a/src/net/sf/freecol/common/model/Specification.java +++ b/src/net/sf/freecol/common/model/Specification.java @@ -90,6 +90,7 @@ public final class Specification implements OptionContainer { = new Class[] { String.class, Specification.class }; // Special reader classes for spec objects + @FunctionalInterface private interface ChildReader { public void readChildren(FreeColXMLReader xr) throws XMLStreamException; } @@ -166,7 +167,7 @@ private void readChild(FreeColXMLReader xr) throws XMLStreamException { Specification.this.addOptionGroup(group, recursive); } else { - logger.warning(OptionGroup.TAG + " expected in OptionReader" + if (logger.isLoggable(Level.WARNING)) logger.warning(OptionGroup.TAG + " expected in OptionReader" + ", not: " + tag); xr.nextTag(); } @@ -210,14 +211,14 @@ public void readChildren(FreeColXMLReader xr) final String tag = xr.getLocalName(); String id = xr.readId(); if (id == null) { - logger.warning("Null identifier, tag: " + tag); + if (logger.isLoggable(Level.WARNING)) logger.warning("Null identifier, tag: " + tag); } else if (FreeColSpecObjectType.DELETE_TAG.equals(tag)) { FreeColSpecObjectType object = removeType(id); if (object != null) { result.remove(object); } else { - logger.warning("Delete " + id + " failed"); + if (logger.isLoggable(Level.WARNING)) logger.warning("Delete " + id + " failed"); } } else { @@ -603,24 +604,25 @@ public boolean loadMods(List mods) { initialized = false; boolean loadedMod = false; for (FreeColModFile mod : mods) { - InputStream sis = null; + InputStream sis; try { - if ((sis = mod.getSpecificationInputStream()) != null) { + sis = mod.getSpecificationInputStream(); + if (sis != null) { // Some mods are resource only load(sis); } loadedMod = true; - logger.info("Loaded mod " + mod.getId()); + if (logger.isLoggable(Level.INFO)) logger.info("Loaded mod " + mod.getId()); } catch (FreeColUserMessageException e) { throw e; } catch (IOException|XMLStreamException ex) { - logger.log(Level.WARNING, "Read error in mod " + mod.getId(), ex); + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Read error in mod " + mod.getId(), ex); throw new FreeColUserMessageException( StringTemplate.template("error.mod").add("%id%", mod.getId()).add("%name%", Messages.getName("mod." + mod.getId())), ex ); - } catch (RuntimeException rte) { - logger.log(Level.WARNING, "Parse error in mod " + mod.getId(), rte); + } catch (IllegalArgumentException rte) { + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Parse error in mod " + mod.getId(), rte); throw new FreeColUserMessageException( StringTemplate.template("error.mod").add("%id%", mod.getId()).add("%name%", Messages.getName("mod." + mod.getId())), rte @@ -676,7 +678,7 @@ public void prepare(Advantages advantages, OptionGroup difficulty) { * be cleaned. */ public void clean(String why) { - logger.finest("Cleaning up specification following " + why + "."); + if (logger.isLoggable(Level.FINEST)) logger.finest("Cleaning up specification following " + why + "."); // Fix up the GoodsType derived attributes. Several GoodsType // predicates are likely to fail until this is done. @@ -814,7 +816,7 @@ public void clean(String why) { } } if (badAges) { - logger.warning("Bad ages: " + agesValue); + if (logger.isLoggable(Level.WARNING)) logger.warning("Bad ages: " + agesValue); ages[0] = 1; // First turn ages[1] = Turn.yearToTurn(1600); ages[2] = Turn.yearToTurn(1700); @@ -856,7 +858,7 @@ public void clean(String why) { .append(", ").append(unitChangeTypeList.size()).append(" UnitChangeTypes") .append(", ").append(unitTypeList.size()).append(" UnitTypes") .append(" read."); - logger.info(sb.toString()); + if (logger.isLoggable(Level.INFO)) logger.info(sb.toString()); } @@ -1026,7 +1028,9 @@ private int compareVersion(String other) { if (cmp != 0) return cmp; return Integer.compare(Integer.parseInt(sv[1]), Integer.parseInt(so[1])); - } catch (NumberFormatException nfe) {} + } catch (NumberFormatException nfe) { + if (logger.isLoggable(Level.FINE)) logger.log(Level.FINE, "Invalid version: " + version + " vs " + other, nfe); + } } throw new RuntimeException("Bad version: " + other); } @@ -2065,7 +2069,7 @@ private T newType(String id, return Introspector.instantiate(returnClass, newTypeClasses, new Object[] { id, this }); } catch (Introspector.IntrospectorException ie) { - logger.log(Level.WARNING, "newType(" + id + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "newType(" + id + "," + returnClass.getName() + ") failed", ie); } return null; @@ -2168,11 +2172,11 @@ private boolean fixOrphanOptions() { // Drop from actual allOptions map dropOptions(ao, allOptions.values()); if (ao instanceof OptionGroup) allOptionGroups.remove(ao.getId()); - logger.warning("Dropping orphan option: " + ao); + if (logger.isLoggable(Level.WARNING)) logger.warning("Dropping orphan option: " + ao); } for (AbstractOption ao : allG) { allOptionGroups.remove(ao.getId()); - logger.warning("Dropping orphan option group: " + ao); + if (logger.isLoggable(Level.WARNING)) logger.warning("Dropping orphan option group: " + ao); } return !allO.isEmpty() || !allG.isEmpty(); } @@ -2217,7 +2221,7 @@ private boolean fixRoles() { return false; } - logger.info("Loading role backward compatibility fragment: " + if (logger.isLoggable(Level.INFO)) logger.info("Loading role backward compatibility fragment: " + ROLES_COMPAT_FILE_NAME + " with roles: " + transform(getRoles(), alwaysTrue(), Role::getId, Collectors.joining(" "))); @@ -2245,7 +2249,7 @@ private boolean fixUnitChanges() { unitChangeTypeList.add(enter); } - logger.info("Loading unit-changes backward compatibility fragment: " + if (logger.isLoggable(Level.INFO)) logger.info("Loading unit-changes backward compatibility fragment: " + UNIT_CHANGE_TYPES_COMPAT_FILE_NAME + " with changes: " + transform(getUnitChangeTypeList(), alwaysTrue(), UnitChangeType::getId, Collectors.joining(" "))); @@ -3123,7 +3127,7 @@ private > boolean checkOp(String id, String gr, new Class[] { String.class, Specification.class }, new Object[] { id, this }); } catch (Introspector.IntrospectorException ie) { - logger.warning("Failed to make " + returnClass.getName() + if (logger.isLoggable(Level.WARNING)) logger.warning("Failed to make " + returnClass.getName() + ": " + id); return false; } @@ -3252,7 +3256,7 @@ public void readFromXML(FreeColXMLReader xr) throws XMLStreamException { version = xr.getAttribute(VERSION_TAG, (String)null); } - logger.fine("Reading specification " + newId + if (logger.isLoggable(Level.FINE)) logger.fine("Reading specification " + newId + " difficulty=" + difficultyLevel + " version=" + version); @@ -3263,7 +3267,7 @@ public void readFromXML(FreeColXMLReader xr) throws XMLStreamException { FreeColModFile parent = FreeColRules.getFreeColRulesFile(parentId); try { load(parent.getSpecificationInputStream()); - } catch (RuntimeException|XMLStreamException e) { + } catch (IllegalArgumentException | XMLStreamException e) { throw new FreeColUserMessageException( StringTemplate.template("error.mod").add("%id%", parent.getId()).add("%name%", Messages.getName("mod." + parent.getId())), e @@ -3285,7 +3289,7 @@ public void readFromXML(FreeColXMLReader xr) throws XMLStreamException { // end @compat 0.11.0 ChildReader reader = readerMap.get(childName); if (reader == null) { - logger.warning("No reader found for: " + childName); + if (logger.isLoggable(Level.WARNING)) logger.warning("No reader found for: " + childName); } else { reader.readChildren(xr); } @@ -3293,7 +3297,9 @@ public void readFromXML(FreeColXMLReader xr) throws XMLStreamException { } /** - * {@inheritDoc} + * Gets the XML tag name for serialization. + * + * @return The XML tag name. */ public String getXMLTagName() { return TAG; } } diff --git a/src/net/sf/freecol/common/model/StringTemplate.java b/src/net/sf/freecol/common/model/StringTemplate.java index 554086347f..77765e7061 100644 --- a/src/net/sf/freecol/common/model/StringTemplate.java +++ b/src/net/sf/freecol/common/model/StringTemplate.java @@ -195,7 +195,7 @@ protected T setDefaultId(final String id, try { return returnClass.cast(this); } catch (ClassCastException cce) { - logger.log(Level.WARNING, "Invalid class " + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Invalid class " + this.getClass() + " referenced.", cce); } return null; diff --git a/src/net/sf/freecol/common/model/Tile.java b/src/net/sf/freecol/common/model/Tile.java index a72a4f5089..64110b6836 100644 --- a/src/net/sf/freecol/common/model/Tile.java +++ b/src/net/sf/freecol/common/model/Tile.java @@ -1090,7 +1090,7 @@ private StringTemplate getNearLocationLabel(Direction direction, * @return A suitable {@code StringTemplate}. */ private StringTemplate getDetailedLocationLabel() { - Settlement nearSettlement = null; + Settlement nearSettlement; for (Tile tile : getSurroundingTiles(NEAR_RADIUS)) { nearSettlement = tile.getSettlement(); if (nearSettlement != null && nearSettlement.getName() != null) { @@ -1125,7 +1125,7 @@ private StringTemplate getDetailedLocationLabel() { * @return A suitable {@code StringTemplate}. */ private StringTemplate getDetailedLocationLabelFor(Player player) { - Settlement nearSettlement = null; + Settlement nearSettlement; for (Tile tile : getSurroundingTiles(NEAR_RADIUS)) { nearSettlement = tile.getSettlement(); if (nearSettlement != null @@ -1280,7 +1280,6 @@ public boolean isGoodHillTile() { * * Used by the terrain generator. * - * @param mountains The mountain tile type. * @return True if this is a good potential elevated tile. */ public boolean isGoodMountainTile() { @@ -1610,14 +1609,15 @@ public StringTemplate getBuildColonyWarnings(Unit unit) { java.util.Map goodsMap = new HashMap<>(typeList.size()); for (GoodsType goodsType : typeList) { - if (goodsType.isBuildingMaterial()) { - while (goodsType.isRefined()) { - goodsType = goodsType.getInputType(); + GoodsType actualType = goodsType; + if (actualType.isBuildingMaterial()) { + while (actualType.isRefined()) { + actualType = actualType.getInputType(); } - } else if (!goodsType.isFoodType()) { + } else if (!actualType.isFoodType()) { continue; } - goodsMap.put(goodsType, 0); + goodsMap.put(actualType, 0); } // Supercede with positive unattended production from this tile for (ProductionType productionType : getType() @@ -2165,7 +2165,7 @@ && hasSettlement()) { // to throw. u = settlement.getDefendingUnit(attacker); } catch (IllegalStateException e) { - logger.log(Level.WARNING, "Empty settlement: " + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Empty settlement: " + settlement.getName(), e); } // This routine can be called on the client for the pre-combat @@ -2262,11 +2262,9 @@ public boolean add(Locatable locatable) { return addTileItem((TileItem) locatable);//-til } else if (locatable instanceof Unit) { - if (super.add(locatable)) { - ((Unit)locatable).setState(Unit.UnitState.ACTIVE); - return true; - } - return false; + if (!super.add(locatable)) return false; + ((Unit)locatable).setState(Unit.UnitState.ACTIVE); + return true; } else { return super.add(locatable); @@ -2544,22 +2542,25 @@ public void toXML(FreeColXMLWriter xw, String tag) throws XMLStreamException { if (player == null) { // 1. Not writing to a player, just write tile. this.internalToXML(xw, tag); - } else if ((tile = getCachedTile(player)) != null) { // 2. Cached tile. - tile.internalToXML(xw, tag); + } else { + tile = getCachedTile(player); + if (tile != null) { // 2. Cached tile. + tile.internalToXML(xw, tag); - } else if (isExploredBy(player)) { // 3. Tile is explored, write it - this.internalToXML(xw, tag); + } else if (isExploredBy(player)) { // 3. Tile is explored, write it + this.internalToXML(xw, tag); - } else { // 4. Tile is not explored. - xw.writeStartElement(tag); + } else { // 4. Tile is not explored. + xw.writeStartElement(tag); - xw.writeAttribute(ID_ATTRIBUTE_TAG, getId()); + xw.writeAttribute(ID_ATTRIBUTE_TAG, getId()); - xw.writeAttribute(X_TAG, this.x); + xw.writeAttribute(X_TAG, this.x); - xw.writeAttribute(Y_TAG, this.y); + xw.writeAttribute(Y_TAG, this.y); - xw.writeEndElement(); + xw.writeEndElement(); + } } } @@ -2789,7 +2790,7 @@ protected void readChild(FreeColXMLReader xr) throws XMLStreamException { int apparent; if (colony != null && (apparent = colony.getApparentUnitCount()) <= 0) { - logger.warning("Copied colony " + colony.getId() + if (logger.isLoggable(Level.WARNING)) logger.warning("Copied colony " + colony.getId() + " display unit count set to 1 from corrupt: " + apparent); colony.setDisplayUnitCount(1); diff --git a/src/net/sf/freecol/common/model/TileImprovement.java b/src/net/sf/freecol/common/model/TileImprovement.java index 3fb2659124..5a67296e4a 100644 --- a/src/net/sf/freecol/common/model/TileImprovement.java +++ b/src/net/sf/freecol/common/model/TileImprovement.java @@ -37,6 +37,7 @@ import net.sf.freecol.common.model.Map.Layer; import net.sf.freecol.common.util.LogBuilder; import net.sf.freecol.common.util.RandomChoice; +import java.util.logging.Level; /** @@ -760,7 +761,7 @@ protected void readAttributes(FreeColXMLReader xr) throws XMLStreamException { List dirns = getConnectionDirections(); if (dirns == null) { if (str != null && !str.isEmpty()) - logger.warning("At " + tile + " ignored nonempty style for " + if (logger.isLoggable(Level.WARNING)) logger.warning("At " + tile + " ignored nonempty style for " + type + ": " + str); } else if (str == null) { // Null style OK for incomplete roads. Virtual roads used @@ -769,7 +770,7 @@ protected void readAttributes(FreeColXMLReader xr) throws XMLStreamException { // complaining about these as they will get fixed and // logged in checkIntegrity(). } else if (str.length() != dirns.size()) { - logger.warning("At " + tile + " ignored bogus style for " + if (logger.isLoggable(Level.WARNING)) logger.warning("At " + tile + " ignored bogus style for " + type + ": " + str); } else { style = TileImprovementStyle.getInstance(str); diff --git a/src/net/sf/freecol/common/model/TileImprovementType.java b/src/net/sf/freecol/common/model/TileImprovementType.java index 61935430ca..46603ade7e 100644 --- a/src/net/sf/freecol/common/model/TileImprovementType.java +++ b/src/net/sf/freecol/common/model/TileImprovementType.java @@ -474,8 +474,9 @@ public int getImprovementValue(Tile tile, GoodsType goodsType, UnitType unitType * Gets the increase in production of the given GoodsType * this tile improvement type would yield at a specified tile. * - * @param tile The {@code Tile} to be considered. + * @param tileType The {@code TileType} to be considered. * @param goodsType An optional preferred {@code GoodsType}. + * @param unitType An optional {@code UnitType} to produce them. * @return The increase in production */ public int getImprovementValue(TileType tileType, GoodsType goodsType, UnitType unitType) { diff --git a/src/net/sf/freecol/common/model/TileItem.java b/src/net/sf/freecol/common/model/TileItem.java index 24bc10749f..9c2a7b2898 100644 --- a/src/net/sf/freecol/common/model/TileItem.java +++ b/src/net/sf/freecol/common/model/TileItem.java @@ -57,6 +57,7 @@ protected TileItem(Game game, Tile tile) { * @param game The enclosing {@code Game}. * @param xr The input stream containing the XML. */ + @SuppressWarnings("PMD.UnusedFormalParameter") public TileItem(Game game, FreeColXMLReader xr) { super(game, null); } diff --git a/src/net/sf/freecol/common/model/TileItemContainer.java b/src/net/sf/freecol/common/model/TileItemContainer.java index 014b3965c3..f59a57e5fc 100644 --- a/src/net/sf/freecol/common/model/TileItemContainer.java +++ b/src/net/sf/freecol/common/model/TileItemContainer.java @@ -33,6 +33,7 @@ import net.sf.freecol.common.model.Map.Layer; import static net.sf.freecol.common.util.CollectionUtils.*; import net.sf.freecol.common.util.LogBuilder; +import java.util.logging.Level; /** @@ -350,7 +351,7 @@ public boolean hasImprovement(TileImprovementType type) { */ public void removeIncompatibleImprovements() { TileType tileType = tile.getType(); - boolean removed = false; + boolean removed; synchronized (tileItems) { TileImprovement river = getRiver(); if(river != null && !river.isTileTypeAllowed(tileType) @@ -489,7 +490,7 @@ public void copyFrom(TileItemContainer tic, Layer layer) { result.add(tileImprovement); } } else { - logger.warning("Bogus tile item: " + item.getId()); + if (logger.isLoggable(Level.WARNING)) logger.warning("Bogus tile item: " + item.getId()); } } setTileItems(result); @@ -557,7 +558,7 @@ public IntegrityType checkIntegrity(boolean fix, LogBuilder lb) { } if (!integ.safe()) { - logger.warning("Removing broken TileImprovement: " + if (logger.isLoggable(Level.WARNING)) logger.warning("Removing broken TileImprovement: " + ti.getId()); removeTileItem(ti); integ = integ.fix(); diff --git a/src/net/sf/freecol/common/model/Turn.java b/src/net/sf/freecol/common/model/Turn.java index 35f3d7271b..89bee0884c 100644 --- a/src/net/sf/freecol/common/model/Turn.java +++ b/src/net/sf/freecol/common/model/Turn.java @@ -40,7 +40,7 @@ public class Turn { /** The numerical value of the Turn, never less than one. */ - private int turn = 1; + private int turn; /** diff --git a/src/net/sf/freecol/common/model/Unit.java b/src/net/sf/freecol/common/model/Unit.java index 6201c67f4f..952a838583 100644 --- a/src/net/sf/freecol/common/model/Unit.java +++ b/src/net/sf/freecol/common/model/Unit.java @@ -59,6 +59,7 @@ import net.sf.freecol.common.model.pathfinding.GoalDeciders; import net.sf.freecol.common.option.GameOptions; import net.sf.freecol.common.util.LogBuilder; +import java.util.logging.Level; /** @@ -126,15 +127,15 @@ public boolean check(Unit u, PathNode path) { if (t == null || t == this.exclude) return false; Settlement settlement = t.getSettlement(); int value; - if (settlement != null - && u.getOwner().owns(settlement) - && (!this.coastal || settlement.isConnectedPort()) - && (value = path.getTotalTurns()) < bestValue) { - bestValue = value; - best = path; - return true; + if (settlement == null + || !u.getOwner().owns(settlement) + || (this.coastal && !settlement.isConnectedPort()) + || (value = path.getTotalTurns()) >= bestValue) { + return false; } - return false; + bestValue = value; + best = path; + return true; } }; @@ -744,7 +745,7 @@ public boolean checkSetState(UnitState s) { case SKIPPED: return getState() == UnitState.ACTIVE; default: - logger.warning("Invalid unit state: " + s); + if (logger.isLoggable(Level.WARNING)) logger.warning("Invalid unit state: " + s); return false; } } @@ -857,7 +858,7 @@ public void changeOwner(Player owner) { if (oldOwner == owner) return; if (oldOwner == null) { - logger.warning("Unit " + getId() + if (logger.isLoggable(Level.WARNING)) logger.warning("Unit " + getId() + " had no owner, when changing owner to " + owner.getId()); } @@ -1632,12 +1633,14 @@ public final void setEthnicity(String newEthnicity) { * @return Whether this unit looks native or not. */ public boolean hasNativeEthnicity() { + if (this.ethnicity == null) return false; + if (getGame() == null || getGame().getSpecification() == null) return false; try { // FIXME: getNation() could fail, but getNationType() // doesn't work as expected return getGame().getSpecification().getNation(ethnicity) .getType().isIndian(); - } catch (Exception e) { + } catch (IllegalArgumentException e) { return false; } } @@ -2700,7 +2703,7 @@ public Tile getBestEntryTile(Tile tile) { */ public Location resolveDestination() { if (!isAtSea()) throw new RuntimeException("Not at sea: " + this); - Tile ret = null; + Tile ret; // Is there a destination, either explicit or by trade route? TradeRouteStop stop = getStop(); Location dst = (TradeRoute.isStopValid(this, stop)) @@ -2716,7 +2719,7 @@ public Location resolveDestination() { : getFullEntryLocation(); // Apparently this can still be null!?! At least log such cases if (ret == null) { - logger.warning("resolveDestination(" + dst + if (logger.isLoggable(Level.WARNING)) logger.warning("resolveDestination(" + dst + ") is null for: " + this); } return ret; @@ -3423,11 +3426,11 @@ public boolean check(Unit unit, PathNode path) { && (p = u.findPath(start)) != null && p.getTotalTurns() < range); }; - if (any(transform(tile.getUnits(), attackerPred))) { - found = path; - return true; + if (!any(transform(tile.getUnits(), attackerPred))) { + return false; } - return false; + found = path; + return true; } }; // The range to search will depend on the speed of the other @@ -4194,7 +4197,7 @@ public boolean setLocation(Location newLocation) { if (newLocation == this.location) return true; if (newLocation != null && !newLocation.canAdd(this)) { - logger.warning("Can not add " + this + " to " + newLocation); + if (logger.isLoggable(Level.WARNING)) logger.warning("Can not add " + this + " to " + newLocation); return false; } @@ -4339,7 +4342,7 @@ public boolean remove(Locatable locatable) { return true; } } else { - logger.warning("Tried to remove from unit: " + if (logger.isLoggable(Level.WARNING)) logger.warning("Tried to remove from unit: " + locatable); } return false; diff --git a/src/net/sf/freecol/common/model/UnitLocation.java b/src/net/sf/freecol/common/model/UnitLocation.java index 5573974a63..41dbc8fab0 100644 --- a/src/net/sf/freecol/common/model/UnitLocation.java +++ b/src/net/sf/freecol/common/model/UnitLocation.java @@ -33,6 +33,7 @@ import net.sf.freecol.common.io.FreeColXMLWriter; import static net.sf.freecol.common.util.CollectionUtils.*; import static net.sf.freecol.common.util.StringUtils.*; +import java.util.logging.Level; /** @@ -180,7 +181,7 @@ public void intern() { */ private boolean addUnit(Unit u) { if (u == null) return false; - boolean ret = false; + boolean ret; u.setLocationNoUpdate(this); synchronized (this.units) { ret = this.units.add(u); @@ -344,11 +345,11 @@ public boolean add(Locatable locatable) { } else if (locatable instanceof Goods) { // dumping goods is a valid action locatable.setLocation(null); - logger.finest("Dumped " + locatable + " in UnitLocation with id " + if (logger.isLoggable(Level.FINEST)) logger.finest("Dumped " + locatable + " in UnitLocation with id " + getId()); return true; } else { - logger.warning("Tried to add Locatable " + locatable + if (logger.isLoggable(Level.WARNING)) logger.warning("Tried to add Locatable " + locatable + " to UnitLocation with id " + getId() + "."); } return false; @@ -367,7 +368,7 @@ public boolean remove(Locatable locatable) { unit.setLocationNoUpdate(null); return true; } else { - logger.warning("Tried to remove non-Unit " + locatable + if (logger.isLoggable(Level.WARNING)) logger.warning("Tried to remove non-Unit " + locatable + " from UnitLocation: " + getId()); return false; } @@ -590,7 +591,7 @@ protected void writeChildren(FreeColXMLWriter xw) throws XMLStreamException { // Do *not* use getUnits/List here, because Colony lies! for (Unit unit : this.units) { if (unit.getLocation() != this) { - logger.warning("UnitLocation " + this + if (logger.isLoggable(Level.WARNING)) logger.warning("UnitLocation " + this + " contains unit " + unit + " with bogus location " + unit.getLocation() + ", fixing."); diff --git a/src/net/sf/freecol/common/model/UnitType.java b/src/net/sf/freecol/common/model/UnitType.java index 8ec03fba7e..87d317c247 100644 --- a/src/net/sf/freecol/common/model/UnitType.java +++ b/src/net/sf/freecol/common/model/UnitType.java @@ -118,7 +118,7 @@ public final class UnitType extends BuildableType implements Consumer { private UnitType skillTaught = null; /** The default role for a unit of this type. */ - private Role defaultRole = null; + private Role defaultRole; /** The goods consumed per turn when in a settlement. */ private TypeCountMap consumption = null; diff --git a/src/net/sf/freecol/common/model/WorkLocation.java b/src/net/sf/freecol/common/model/WorkLocation.java index 718e3633b4..92a4a340ce 100644 --- a/src/net/sf/freecol/common/model/WorkLocation.java +++ b/src/net/sf/freecol/common/model/WorkLocation.java @@ -161,7 +161,7 @@ public final void setProductionType(final ProductionType newProductionType) { if (!Utils.equals(newProductionType, this.productionType)) { this.productionType = newProductionType; getColony().invalidateCache(); - logger.fine("Production type at " + this + if (logger.isLoggable(Level.FINE)) logger.fine("Production type at " + this + " is now: " + newProductionType); } } @@ -388,18 +388,24 @@ public java.util.Map getSuggestions() { Suggestion sug; // Check if the existing non-student units can be improved. for (Unit u : transform(getUnits(), isNull(Unit::getTeacher))) { - if ((work = u.getWorkType()) == null) { - if (occ != null) work = occ.workType; + work = u.getWorkType(); + if (work == null && occ != null) { + work = occ.workType; } - if ((sug = getSuggestion(u, getProductionType(), work)) != null) { + sug = getSuggestion(u, getProductionType(), work); + if (sug != null) { result.put(u, sug); } } // Check for a suggestion for an extra worker if there is space. - if (occ != null && (work = occ.workType) != null - && !isFull() - && (sug = getSuggestion(null, occ.productionType, work)) != null) { - result.put(null, sug); + if (occ != null) { + work = occ.workType; + if (work != null && !isFull()) { + sug = getSuggestion(null, occ.productionType, work); + if (sug != null) { + result.put(null, sug); + } + } } return result; } diff --git a/src/net/sf/freecol/common/model/mission/AbstractMission.java b/src/net/sf/freecol/common/model/mission/AbstractMission.java index b6ec0e95d8..edcfa0e8b1 100644 --- a/src/net/sf/freecol/common/model/mission/AbstractMission.java +++ b/src/net/sf/freecol/common/model/mission/AbstractMission.java @@ -69,6 +69,7 @@ public AbstractMission(Game game, String id) { * @param game a {@code Game} value * @param xr a {@code FreeColXMLReader} value */ + @SuppressWarnings("PMD.UnusedFormalParameter") protected AbstractMission(Game game, FreeColXMLReader xr) { super(game, null); } diff --git a/src/net/sf/freecol/common/model/mission/MissionManager.java b/src/net/sf/freecol/common/model/mission/MissionManager.java index b306277c15..9a501c11ab 100644 --- a/src/net/sf/freecol/common/model/mission/MissionManager.java +++ b/src/net/sf/freecol/common/model/mission/MissionManager.java @@ -20,6 +20,7 @@ package net.sf.freecol.common.model.mission; import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; import java.util.HashMap; import java.util.Map; import java.util.logging.Level; @@ -82,14 +83,15 @@ public static Mission getMission(Game game, String tag = xr.getLocalName(); Constructor c = missionMap.get(tag); if (c == null) { - logger.warning("Unknown type of mission: '" + tag + "'."); + if (logger.isLoggable(Level.WARNING)) logger.warning("Unknown type of mission: '" + tag + "'."); xr.nextTag(); return null; } else { try { return c.newInstance(game, xr); - } catch (Exception e) { - logger.log(Level.WARNING, "Failed to instatiate mission with tag: " + } catch (InstantiationException | IllegalAccessException + | InvocationTargetException | IllegalArgumentException e) { + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Failed to instatiate mission with tag: " + tag, e); return null; } diff --git a/src/net/sf/freecol/common/model/package-info.java b/src/net/sf/freecol/common/model/package-info.java index 0bdc3070ff..adae745395 100644 --- a/src/net/sf/freecol/common/model/package-info.java +++ b/src/net/sf/freecol/common/model/package-info.java @@ -1,5 +1,5 @@ /** - *

FreeCol Game Model package

+ *

FreeCol Game Model package

* *

This package contains the game model, which describes how the * individual game objects, such as units, buildings, tiles and so on, diff --git a/src/net/sf/freecol/common/model/pathfinding/BaseCostDecider.java b/src/net/sf/freecol/common/model/pathfinding/BaseCostDecider.java index b4c9e5f12c..f695705c42 100644 --- a/src/net/sf/freecol/common/model/pathfinding/BaseCostDecider.java +++ b/src/net/sf/freecol/common/model/pathfinding/BaseCostDecider.java @@ -55,7 +55,7 @@ class BaseCostDecider implements CostDecider { @Override public int getCost(final Unit unit, final Location oldLocation, final Location newLocation, int movesLeftBefore) { - int cost = 0; + int cost; this.newTurns = 0; Tile oldTile = oldLocation.getTile(); diff --git a/src/net/sf/freecol/common/model/pathfinding/CostDeciders.java b/src/net/sf/freecol/common/model/pathfinding/CostDeciders.java index dc94be1094..ff50f59310 100644 --- a/src/net/sf/freecol/common/model/pathfinding/CostDeciders.java +++ b/src/net/sf/freecol/common/model/pathfinding/CostDeciders.java @@ -257,6 +257,7 @@ public static CostDecider getComposedCostDecider(final CostDecider... cds) { @Override public int getCost(Unit unit, Location oldLocation, Location newLocation, int movesLeft) { + int bestIndex = -1; for (int i = 0; i < costDeciders.length; i++) { int cost = costDeciders[i].getCost(unit, oldLocation, newLocation, movesLeft); @@ -265,10 +266,11 @@ public int getCost(Unit unit, Location oldLocation, return ILLEGAL_MOVE; } if (cost > ret) { - index = i; + bestIndex = i; ret = cost; } } + index = bestIndex; return ret; } diff --git a/src/net/sf/freecol/common/model/pathfinding/GoalDeciders.java b/src/net/sf/freecol/common/model/pathfinding/GoalDeciders.java index 6403c0dceb..7d6efbe7a8 100644 --- a/src/net/sf/freecol/common/model/pathfinding/GoalDeciders.java +++ b/src/net/sf/freecol/common/model/pathfinding/GoalDeciders.java @@ -94,12 +94,10 @@ public boolean check(Unit u, PathNode path) { } } } - if (all) { - this.winner = 0; - this.goal = path; - return true; - } - return false; + if (!all) return false; + this.winner = 0; + this.goal = path; + return true; } }; } @@ -186,12 +184,9 @@ public static GoalDecider getSimpleHighSeasGoalDecider() { @Override public boolean check(Unit u, PathNode path) { Tile tile = path.getTile(); - if (tile != null - && tile.isDirectlyHighSeasConnected()) { - first = path; - return true; - } - return false; + if (tile == null || !tile.isDirectlyHighSeasConnected()) return false; + first = path; + return true; } }; } @@ -214,15 +209,13 @@ public static GoalDecider getLocationGoalDecider(final Location target) { public boolean hasSubGoals() { return false; } @Override public boolean check(Unit u, PathNode path) { - int cost; - if (Map.isSameLocation(path.getLocation(), target)) { - if ((cost = path.getCost()) < bestCost) { - best = path; - bestCost = cost; - } - return true; + if (!Map.isSameLocation(path.getLocation(), target)) return false; + int cost = path.getCost(); + if (cost < bestCost) { + best = path; + bestCost = cost; } - return false; + return true; } }; } @@ -248,11 +241,9 @@ public static GoalDecider getAdjacentLocationGoalDecider(Location target) { @Override public boolean check(Unit u, PathNode path) { Tile t = path.getTile(); - if (t != null && t.isAdjacent(tile)) { - best = path; - return true; - } - return false; + if (t == null || !t.isAdjacent(tile)) return false; + best = path; + return true; } }; } @@ -278,11 +269,9 @@ public boolean check(Unit u, PathNode path) { if (t == null || !t.isLand()) return false; Settlement s = t.getSettlement(); if (s == null) return false; - if (enemies.contains(s.getOwner())) { - best = path; - return true; - } - return false; + if (!enemies.contains(s.getOwner())) return false; + best = path; + return true; } }; } @@ -336,14 +325,12 @@ public boolean check(Unit u, PathNode pathNode) { ? NO_DANGER_BONUS : 0.0))); Tile best = maximize(tile.getSurroundingTiles(1, 1), dockPred, Comparator.comparingDouble(tileScorer)); - double score; - if (best != null - && (score = tileScorer.applyAsDouble(best)) > bestScore) { - bestScore = score; - goal = pathNode; - return true; - } - return false; + if (best == null) return false; + double score = tileScorer.applyAsDouble(best); + if (score <= bestScore) return false; + bestScore = score; + goal = pathNode; + return true; } }; } @@ -425,12 +412,12 @@ public static GoalDecider getCornerGoalDecider() { @Override public boolean check(Unit u, PathNode pathNode) { Tile tile = pathNode.getTile(); - if (tile.getHighSeasCount() < score && tile.isRiverCorner()) { - score = tile.getHighSeasCount(); - goal = pathNode; - return true; + if (tile.getHighSeasCount() >= score || !tile.isRiverCorner()) { + return false; } - return false; + score = tile.getHighSeasCount(); + goal = pathNode; + return true; } }; } diff --git a/src/net/sf/freecol/common/model/production/TileProductionCalculator.java b/src/net/sf/freecol/common/model/production/TileProductionCalculator.java index 70957e7889..20b14cd66e 100644 --- a/src/net/sf/freecol/common/model/production/TileProductionCalculator.java +++ b/src/net/sf/freecol/common/model/production/TileProductionCalculator.java @@ -296,8 +296,11 @@ public Stream getProductionModifiers(Turn turn, Tile tile, GoodsType g * Gets the production modifiers for the given type of goods on * the colony center tile. * + * @param turn The {@code Turn} in which production occurs. + * @param tile The center {@code Tile} to evaluate. * @param goodsType The {@code GoodsType} to produce. - * @param unitType The optional {@code UnitType} to produce them. + * @param additionalTileImprovements Additional {@code TileImprovementType}s + * to apply in the calculation. * @return A stream of the applicable modifiers. */ public Stream getCenterTileProductionModifiers(Turn turn, Tile tile, GoodsType goodsType, List additionalTileImprovements) { diff --git a/src/net/sf/freecol/common/networking/AbandonColonyMessage.java b/src/net/sf/freecol/common/networking/AbandonColonyMessage.java index f9e70c4cc5..762050e2a9 100644 --- a/src/net/sf/freecol/common/networking/AbandonColonyMessage.java +++ b/src/net/sf/freecol/common/networking/AbandonColonyMessage.java @@ -87,7 +87,7 @@ public ChangeSet serverHandler(FreeColServer freeColServer, Colony colony; try { colony = serverPlayer.getOurFreeColGameObject(colonyId, Colony.class); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } int count = colony.getUnitCount(); diff --git a/src/net/sf/freecol/common/networking/AnimateAttackMessage.java b/src/net/sf/freecol/common/networking/AnimateAttackMessage.java index 12a88dfe35..7f70a7bd7f 100644 --- a/src/net/sf/freecol/common/networking/AnimateAttackMessage.java +++ b/src/net/sf/freecol/common/networking/AnimateAttackMessage.java @@ -32,6 +32,7 @@ import net.sf.freecol.common.model.Unit; import net.sf.freecol.server.FreeColServer; import net.sf.freecol.server.ai.AIPlayer; +import java.util.logging.Level; /** @@ -128,9 +129,10 @@ private Unit getUnit(Game game, String key) { u.intern(); return u; } - if ((u = u.getCarriedUnitById(id)) != null) { - u.intern(); - return u; + Unit carried = u.getCarriedUnitById(id); + if (carried != null) { + carried.intern(); + return carried; } } return null; @@ -225,11 +227,11 @@ public void clientHandler(FreeColClient freeColClient) { return; } if (attackerTile == null) { - logger.warning("Attack animation for: " + player.getId() + if (logger.isLoggable(Level.WARNING)) logger.warning("Attack animation for: " + player.getId() + " omitted attacker tile."); } if (defenderTile == null) { - logger.warning("Attack animation for: " + player.getId() + if (logger.isLoggable(Level.WARNING)) logger.warning("Attack animation for: " + player.getId() + " omitted defender tile."); } diff --git a/src/net/sf/freecol/common/networking/AnimateMoveMessage.java b/src/net/sf/freecol/common/networking/AnimateMoveMessage.java index 7e4e7a1e3c..43a9271287 100644 --- a/src/net/sf/freecol/common/networking/AnimateMoveMessage.java +++ b/src/net/sf/freecol/common/networking/AnimateMoveMessage.java @@ -29,6 +29,7 @@ import net.sf.freecol.common.model.Unit; import net.sf.freecol.server.FreeColServer; import net.sf.freecol.server.ai.AIPlayer; +import java.util.logging.Level; /** @@ -107,18 +108,19 @@ public AnimateMoveMessage(Game game, FreeColXMLReader xr) private Unit getUnit(Game game) { final String uid = getStringAttribute(UNIT_TAG); Unit unit = game.getFreeColGameObject(uid, Unit.class); + if (unit != null) return unit; + + unit = getChild(0, Unit.class); if (unit == null) { - if ((unit = getChild(0, Unit.class)) == null) { - logger.warning("Move animation missing unit: " + uid); - } else { - unit.intern(); - if (!unit.getId().equals(uid)) { // actually on carrier - unit = unit.getCarriedUnitById(uid); - if (unit == null) { - logger.warning("Move animation missing carried unit: " - + uid); - } - } + if (logger.isLoggable(Level.WARNING)) logger.warning("Move animation missing unit: " + uid); + return null; + } + + unit.intern(); + if (!unit.getId().equals(uid)) { // actually on carrier + unit = unit.getCarriedUnitById(uid); + if (unit == null && logger.isLoggable(Level.WARNING)) { + logger.warning("Move animation missing carried unit: " + uid); } } return unit; @@ -175,12 +177,12 @@ public void clientHandler(FreeColClient freeColClient) { if (unit == null) return; if (oldTile == null) { - logger.warning("Animation for: " + player.getId() + if (logger.isLoggable(Level.WARNING)) logger.warning("Animation for: " + player.getId() + " missing old Tile."); return; } if (newTile == null) { - logger.warning("Animation for: " + player.getId() + if (logger.isLoggable(Level.WARNING)) logger.warning("Animation for: " + player.getId() + " missing new Tile."); return; } diff --git a/src/net/sf/freecol/common/networking/AskSkillMessage.java b/src/net/sf/freecol/common/networking/AskSkillMessage.java index 88ab311d76..ee3ca80f24 100644 --- a/src/net/sf/freecol/common/networking/AskSkillMessage.java +++ b/src/net/sf/freecol/common/networking/AskSkillMessage.java @@ -96,14 +96,14 @@ public ChangeSet serverHandler(FreeColServer freeColServer, ServerUnit unit; try { unit = serverPlayer.getOurFreeColGameObject(unitId, ServerUnit.class); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } Tile tile; try { tile = unit.getNeighbourTile(directionString); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } diff --git a/src/net/sf/freecol/common/networking/AssignTeacherMessage.java b/src/net/sf/freecol/common/networking/AssignTeacherMessage.java index 57ea85b6b2..af854f9c65 100644 --- a/src/net/sf/freecol/common/networking/AssignTeacherMessage.java +++ b/src/net/sf/freecol/common/networking/AssignTeacherMessage.java @@ -90,14 +90,14 @@ public ChangeSet serverHandler(FreeColServer freeColServer, Unit student; try { student = serverPlayer.getOurFreeColGameObject(studentId, Unit.class); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } Unit teacher; try { teacher = serverPlayer.getOurFreeColGameObject(teacherId, Unit.class); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } diff --git a/src/net/sf/freecol/common/networking/AssignTradeRouteMessage.java b/src/net/sf/freecol/common/networking/AssignTradeRouteMessage.java index d587df05cb..a97fba69a4 100644 --- a/src/net/sf/freecol/common/networking/AssignTradeRouteMessage.java +++ b/src/net/sf/freecol/common/networking/AssignTradeRouteMessage.java @@ -100,7 +100,7 @@ public ChangeSet serverHandler(FreeColServer freeColServer, Unit unit; try { unit = serverPlayer.getOurFreeColGameObject(unitId, Unit.class); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } @@ -111,7 +111,7 @@ public ChangeSet serverHandler(FreeColServer freeColServer, try { tradeRoute = serverPlayer.getOurFreeColGameObject(tradeRouteId, TradeRoute.class); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } } diff --git a/src/net/sf/freecol/common/networking/AttackMessage.java b/src/net/sf/freecol/common/networking/AttackMessage.java index 2e35124fb0..a2e590682b 100644 --- a/src/net/sf/freecol/common/networking/AttackMessage.java +++ b/src/net/sf/freecol/common/networking/AttackMessage.java @@ -94,7 +94,7 @@ public ChangeSet serverHandler(FreeColServer freeColServer, Unit unit; try { unit = serverPlayer.getOurFreeColGameObject(unitId, Unit.class); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } @@ -105,7 +105,7 @@ public ChangeSet serverHandler(FreeColServer freeColServer, Tile tile; try { tile = unit.getNeighbourTile(directionString); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } diff --git a/src/net/sf/freecol/common/networking/AttackRangedMessage.java b/src/net/sf/freecol/common/networking/AttackRangedMessage.java index eeced0c333..85f392b795 100644 --- a/src/net/sf/freecol/common/networking/AttackRangedMessage.java +++ b/src/net/sf/freecol/common/networking/AttackRangedMessage.java @@ -92,7 +92,7 @@ public ChangeSet serverHandler(FreeColServer freeColServer, Unit unit; try { unit = serverPlayer.getOurFreeColGameObject(unitId, Unit.class); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } @@ -103,7 +103,7 @@ public ChangeSet serverHandler(FreeColServer freeColServer, Tile tile; try { tile = freeColServer.getGame().getFreeColGameObject(targetId, Tile.class); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } diff --git a/src/net/sf/freecol/common/networking/BuildColonyMessage.java b/src/net/sf/freecol/common/networking/BuildColonyMessage.java index 70a4c90105..057b4dd833 100644 --- a/src/net/sf/freecol/common/networking/BuildColonyMessage.java +++ b/src/net/sf/freecol/common/networking/BuildColonyMessage.java @@ -93,7 +93,7 @@ public ChangeSet serverHandler(FreeColServer freeColServer, Unit unit; try { unit = serverPlayer.getOurFreeColGameObject(unitId, Unit.class); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } if (!unit.canBuildColony()) { diff --git a/src/net/sf/freecol/common/networking/CashInTreasureTrainMessage.java b/src/net/sf/freecol/common/networking/CashInTreasureTrainMessage.java index f1bdcf4abb..54544fec17 100644 --- a/src/net/sf/freecol/common/networking/CashInTreasureTrainMessage.java +++ b/src/net/sf/freecol/common/networking/CashInTreasureTrainMessage.java @@ -87,7 +87,7 @@ public ChangeSet serverHandler(FreeColServer freeColServer, Unit unit; try { unit = serverPlayer.getOurFreeColGameObject(unitId, Unit.class); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } diff --git a/src/net/sf/freecol/common/networking/ChangeSet.java b/src/net/sf/freecol/common/networking/ChangeSet.java index a0842d179d..ad10ecf818 100644 --- a/src/net/sf/freecol/common/networking/ChangeSet.java +++ b/src/net/sf/freecol/common/networking/ChangeSet.java @@ -360,6 +360,7 @@ public boolean isNotifiable(Player player) { /** * {@inheritDoc} */ + @Override public AnimateAttackMessage toMessage(Player player) { if (!isNotifiable(player)) return null; Unit a = (player.owns(attacker)) ? attacker @@ -417,6 +418,7 @@ public AttributeChange(See see, String key, String value) { /** * {@inheritDoc} */ + @Override public AttributeMessage toMessage(Player player) { return new AttributeMessage(AttributeMessage.TAG, key, value).setMergeable(true); @@ -1451,13 +1453,14 @@ public Message build(Player player) { // splitting out trivial mergeable attribute changes. List messages = new ArrayList<>(); List diverted = new ArrayList<>(); - for (Change c : this.changes) { - if (!c.isNotifiable(player)) continue; - Message m = c.toMessage(player); + for (Change change : this.changes) { + if (!change.isNotifiable(player)) continue; + Message m = change.toMessage(player); List onto = (m.canMerge()) ? diverted : messages; onto.add(m); - if ((c = c.consequence(player)) != null) { - m = c.toMessage(player); + Change consequence = change.consequence(player); + if (consequence != null) { + m = consequence.toMessage(player); onto = (m.canMerge()) ? diverted : messages; onto.add(m); } diff --git a/src/net/sf/freecol/common/networking/ChangeStateMessage.java b/src/net/sf/freecol/common/networking/ChangeStateMessage.java index b27118ee0e..1c90581b5f 100644 --- a/src/net/sf/freecol/common/networking/ChangeStateMessage.java +++ b/src/net/sf/freecol/common/networking/ChangeStateMessage.java @@ -91,7 +91,7 @@ public ChangeSet serverHandler(FreeColServer freeColServer, Unit unit; try { unit = serverPlayer.getOurFreeColGameObject(unitId, Unit.class); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } // Do not test if it is on the map, units in Europe can change state. @@ -99,7 +99,7 @@ public ChangeSet serverHandler(FreeColServer freeColServer, UnitState state; try { state = Enum.valueOf(UnitState.class, stateString); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } if (!unit.checkSetState(state)) { diff --git a/src/net/sf/freecol/common/networking/ChangeWorkImprovementTypeMessage.java b/src/net/sf/freecol/common/networking/ChangeWorkImprovementTypeMessage.java index 0bcc75e4a7..1d6b1019b7 100644 --- a/src/net/sf/freecol/common/networking/ChangeWorkImprovementTypeMessage.java +++ b/src/net/sf/freecol/common/networking/ChangeWorkImprovementTypeMessage.java @@ -95,7 +95,7 @@ public ChangeSet serverHandler(FreeColServer freeColServer, Unit unit; try { unit = serverPlayer.getOurFreeColGameObject(unitId, Unit.class); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } @@ -120,15 +120,18 @@ public ChangeSet serverHandler(FreeColServer freeColServer, } else if (!type.isTileTypeAllowed(tile.getType())) { return serverPlayer.clientError("ImprovementType not allowed on tile: " + improvementId); - } else if ((improvement = tile.getTileImprovement(type)) == null) { - if (!type.isWorkerAllowed(unit)) { - return serverPlayer.clientError("Unit can not create improvement: " - + improvementId); - } - } else { // Has improvement, check if worker can contribute to it - if (!improvement.isWorkerAllowed(unit)) { - return serverPlayer.clientError("Unit can not work on improvement: " - + improvementId); + } else { + improvement = tile.getTileImprovement(type); + if (improvement == null) { + if (!type.isWorkerAllowed(unit)) { + return serverPlayer.clientError("Unit can not create improvement: " + + improvementId); + } + } else { // Has improvement, check if worker can contribute to it + if (!improvement.isWorkerAllowed(unit)) { + return serverPlayer.clientError("Unit can not work on improvement: " + + improvementId); + } } } diff --git a/src/net/sf/freecol/common/networking/ChangeWorkTypeMessage.java b/src/net/sf/freecol/common/networking/ChangeWorkTypeMessage.java index bbfc4360de..8e7280617d 100644 --- a/src/net/sf/freecol/common/networking/ChangeWorkTypeMessage.java +++ b/src/net/sf/freecol/common/networking/ChangeWorkTypeMessage.java @@ -93,7 +93,7 @@ public ChangeSet serverHandler(FreeColServer freeColServer, Unit unit; try { unit = serverPlayer.getOurFreeColGameObject(unitId, Unit.class); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } if (!unit.hasTile()) { diff --git a/src/net/sf/freecol/common/networking/ChatMessage.java b/src/net/sf/freecol/common/networking/ChatMessage.java index 04f3723801..4c79177afb 100644 --- a/src/net/sf/freecol/common/networking/ChatMessage.java +++ b/src/net/sf/freecol/common/networking/ChatMessage.java @@ -20,6 +20,8 @@ package net.sf.freecol.common.networking; import java.awt.Color; +import java.util.logging.Level; +import java.util.logging.Logger; import javax.xml.stream.XMLStreamException; @@ -37,6 +39,8 @@ */ public class ChatMessage extends AttributeMessage { + private static final Logger logger = Logger.getLogger(ChatMessage.class.getName()); + public static final String TAG = "chat"; private static final String COLOR_TAG = "color"; private static final String MESSAGE_TAG = "message"; @@ -66,7 +70,8 @@ public ChatMessage(Player player, String message, boolean privateChat) { * @param xr The {@code FreeColXMLReader} to read from. * @exception XMLStreamException if the stream is corrupt. */ - public ChatMessage(@SuppressWarnings("unused") Game game, + @SuppressWarnings("PMD.UnusedFormalParameter") + public ChatMessage(Game game, FreeColXMLReader xr) throws XMLStreamException { super(TAG, xr, COLOR_TAG, MESSAGE_TAG, SENDER_TAG, PRIVATE_TAG); @@ -134,7 +139,9 @@ public Color getColor() { try { int rgb = getIntegerAttribute(COLOR_TAG, 0); color = new Color(rgb); - } catch (NumberFormatException nfe) {} + } catch (NumberFormatException nfe) { + logger.log(Level.FINE, "Invalid chat color.", nfe); + } return color; } diff --git a/src/net/sf/freecol/common/networking/ClaimLandMessage.java b/src/net/sf/freecol/common/networking/ClaimLandMessage.java index 9ebc41a2a1..8bf9ec602a 100644 --- a/src/net/sf/freecol/common/networking/ClaimLandMessage.java +++ b/src/net/sf/freecol/common/networking/ClaimLandMessage.java @@ -66,6 +66,7 @@ public ClaimLandMessage(Tile tile, FreeColGameObject claimant, int price) { * @param xr The {@code FreeColXMLReader} to read from. * @exception XMLStreamException if the stream is corrupt. */ + @SuppressWarnings("PMD.UnusedFormalParameter") public ClaimLandMessage(Game game, FreeColXMLReader xr) throws XMLStreamException { super(TAG, xr, TILE_TAG, CLAIMANT_TAG, PRICE_TAG); @@ -106,7 +107,7 @@ public ChangeSet serverHandler(FreeColServer freeColServer, Class c = FreeColObject .getFreeColObjectClassByName(FreeColObject.getIdTypeByName(claimantId)); - Unit unit = null; + Unit unit; Settlement settlement = null; if (Unit.class.isAssignableFrom(c)) { unit = serverPlayer.getOurFreeColGameObject(claimantId, Unit.class); diff --git a/src/net/sf/freecol/common/networking/ClearSpecialityMessage.java b/src/net/sf/freecol/common/networking/ClearSpecialityMessage.java index 9b1b6805fa..3ed8ba088c 100644 --- a/src/net/sf/freecol/common/networking/ClearSpecialityMessage.java +++ b/src/net/sf/freecol/common/networking/ClearSpecialityMessage.java @@ -87,7 +87,7 @@ public ChangeSet serverHandler(FreeColServer freeColServer, Unit unit; try { unit = serverPlayer.getOurFreeColGameObject(unitId, Unit.class); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } diff --git a/src/net/sf/freecol/common/networking/CloseMessage.java b/src/net/sf/freecol/common/networking/CloseMessage.java index a6fe52b021..87e816b697 100644 --- a/src/net/sf/freecol/common/networking/CloseMessage.java +++ b/src/net/sf/freecol/common/networking/CloseMessage.java @@ -53,6 +53,7 @@ public CloseMessage(String panel) { * @param xr The {@code FreeColXMLReader} to read from. * @exception XMLStreamException if the stream is corrupt. */ + @SuppressWarnings("PMD.UnusedFormalParameter") public CloseMessage(Game game, FreeColXMLReader xr) throws XMLStreamException { super(TAG, xr, PANEL_TAG); diff --git a/src/net/sf/freecol/common/networking/Connection.java b/src/net/sf/freecol/common/networking/Connection.java index 3b3a084c11..6741923f69 100644 --- a/src/net/sf/freecol/common/networking/Connection.java +++ b/src/net/sf/freecol/common/networking/Connection.java @@ -401,7 +401,7 @@ public String startListen() throws XMLStreamException { if (line == null) return DisconnectMessage.TAG; try { this.xr = new FreeColXMLReader(new StringReader(line)); - } catch (Exception ex) { + } catch (XMLStreamException ex) { return DisconnectMessage.TAG; } this.xr.nextTag(); @@ -506,7 +506,9 @@ protected final void logMessage(Message message, boolean send) { END_OF_STREAM_ARRAY.length); this.lw.flush(); } - } catch (Exception ex) {} + } catch (XMLStreamException | RuntimeException ex) { + logger.log(Level.FINE, "Failed to log message.", ex); + } } @@ -588,6 +590,7 @@ public void send(Message message) /** * Close this connection. */ + @Override public void close() { synchronized (receivingThreadLock) { if (this.receivingThread != null) { @@ -603,7 +606,7 @@ public void close() { closeInputStream(); closeOutputStream(); - logger.fine("Connection closed for " + this.name); + if (logger.isLoggable(Level.FINE)) logger.fine("Connection closed for " + this.name); } diff --git a/src/net/sf/freecol/common/networking/ConnectionVerificationMessage.java b/src/net/sf/freecol/common/networking/ConnectionVerificationMessage.java index 3b8ba696f6..541b3bcfa3 100644 --- a/src/net/sf/freecol/common/networking/ConnectionVerificationMessage.java +++ b/src/net/sf/freecol/common/networking/ConnectionVerificationMessage.java @@ -51,6 +51,7 @@ public ConnectionVerificationMessage(boolean connectable) { * @param xr The {@code FreeColXMLReader} to read from. * @exception XMLStreamException if there is a problem reading the stream. */ + @SuppressWarnings("PMD.UnusedFormalParameter") public ConnectionVerificationMessage(Game game, FreeColXMLReader xr) throws XMLStreamException { super(TAG, xr, CONNECTABLE_TAG); } diff --git a/src/net/sf/freecol/common/networking/DeclareIndependenceMessage.java b/src/net/sf/freecol/common/networking/DeclareIndependenceMessage.java index d97dac3233..add79f56f5 100644 --- a/src/net/sf/freecol/common/networking/DeclareIndependenceMessage.java +++ b/src/net/sf/freecol/common/networking/DeclareIndependenceMessage.java @@ -56,6 +56,7 @@ public DeclareIndependenceMessage(String nationName, String countryName) { * @param xr The {@code FreeColXMLReader} to read from. * @exception XMLStreamException if the stream is corrupt. */ + @SuppressWarnings("PMD.UnusedFormalParameter") public DeclareIndependenceMessage(Game game, FreeColXMLReader xr) throws XMLStreamException { super(TAG, xr, NATION_NAME_TAG, COUNTRY_NAME_TAG); diff --git a/src/net/sf/freecol/common/networking/DeclineMoundsMessage.java b/src/net/sf/freecol/common/networking/DeclineMoundsMessage.java index f757fbd937..c95eca5c36 100644 --- a/src/net/sf/freecol/common/networking/DeclineMoundsMessage.java +++ b/src/net/sf/freecol/common/networking/DeclineMoundsMessage.java @@ -94,14 +94,14 @@ public ChangeSet serverHandler(FreeColServer freeColServer, Unit unit; try { unit = serverPlayer.getOurFreeColGameObject(unitId, Unit.class); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } Tile tile; try { tile = unit.getNeighbourTile(directionString); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } diff --git a/src/net/sf/freecol/common/networking/DeleteTradeRouteMessage.java b/src/net/sf/freecol/common/networking/DeleteTradeRouteMessage.java index afa4fe5379..5e1e42a9c6 100644 --- a/src/net/sf/freecol/common/networking/DeleteTradeRouteMessage.java +++ b/src/net/sf/freecol/common/networking/DeleteTradeRouteMessage.java @@ -97,7 +97,7 @@ public ChangeSet serverHandler(FreeColServer freeColServer, try { tradeRoute = serverPlayer.getOurFreeColGameObject(tradeRouteId, TradeRoute.class); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } diff --git a/src/net/sf/freecol/common/networking/DeliverGiftMessage.java b/src/net/sf/freecol/common/networking/DeliverGiftMessage.java index 1e74e26f4b..4834bcf483 100644 --- a/src/net/sf/freecol/common/networking/DeliverGiftMessage.java +++ b/src/net/sf/freecol/common/networking/DeliverGiftMessage.java @@ -146,7 +146,7 @@ public ChangeSet serverHandler(FreeColServer freeColServer, Unit unit; try { unit = serverPlayer.getOurFreeColGameObject(unitId, Unit.class); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } @@ -154,7 +154,7 @@ public ChangeSet serverHandler(FreeColServer freeColServer, try { is = unit.getAdjacentSettlement(getStringAttribute(SETTLEMENT_TAG), IndianSettlement.class); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } diff --git a/src/net/sf/freecol/common/networking/DemandTributeMessage.java b/src/net/sf/freecol/common/networking/DemandTributeMessage.java index cebbb7b818..5329ef2d1f 100644 --- a/src/net/sf/freecol/common/networking/DemandTributeMessage.java +++ b/src/net/sf/freecol/common/networking/DemandTributeMessage.java @@ -97,7 +97,7 @@ public ChangeSet serverHandler(FreeColServer freeColServer, Unit unit; try { unit = serverPlayer.getOurFreeColGameObject(unitId, Unit.class); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } if (unit.isArmed() @@ -111,7 +111,7 @@ public ChangeSet serverHandler(FreeColServer freeColServer, Tile tile; try { tile = unit.getNeighbourTile(directionString); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } diff --git a/src/net/sf/freecol/common/networking/DisbandUnitMessage.java b/src/net/sf/freecol/common/networking/DisbandUnitMessage.java index 544f98c392..937bca2bb7 100644 --- a/src/net/sf/freecol/common/networking/DisbandUnitMessage.java +++ b/src/net/sf/freecol/common/networking/DisbandUnitMessage.java @@ -87,7 +87,7 @@ public ChangeSet serverHandler(FreeColServer freeColServer, Unit unit; try { unit = serverPlayer.getOurFreeColGameObject(unitId, Unit.class); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } diff --git a/src/net/sf/freecol/common/networking/DisconnectMessage.java b/src/net/sf/freecol/common/networking/DisconnectMessage.java index 7dfa1b3c80..c866f27d78 100644 --- a/src/net/sf/freecol/common/networking/DisconnectMessage.java +++ b/src/net/sf/freecol/common/networking/DisconnectMessage.java @@ -70,7 +70,7 @@ public void aiHandler(FreeColServer freeColServer, AIPlayer aiPlayer) { */ @Override public void clientHandler(FreeColClient freeColClient) { - ; // Do nothing on the client side + // Do nothing on the client side } /** diff --git a/src/net/sf/freecol/common/networking/DisembarkMessage.java b/src/net/sf/freecol/common/networking/DisembarkMessage.java index 386ed32148..6ac262c4e8 100644 --- a/src/net/sf/freecol/common/networking/DisembarkMessage.java +++ b/src/net/sf/freecol/common/networking/DisembarkMessage.java @@ -88,7 +88,7 @@ public ChangeSet serverHandler(FreeColServer freeColServer, ServerUnit unit; try { unit = serverPlayer.getOurFreeColGameObject(unitId, ServerUnit.class); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } diff --git a/src/net/sf/freecol/common/networking/EmbarkMessage.java b/src/net/sf/freecol/common/networking/EmbarkMessage.java index 8e81838f3c..a857165d9c 100644 --- a/src/net/sf/freecol/common/networking/EmbarkMessage.java +++ b/src/net/sf/freecol/common/networking/EmbarkMessage.java @@ -98,14 +98,14 @@ public ChangeSet serverHandler(FreeColServer freeColServer, ServerUnit unit; try { unit = serverPlayer.getOurFreeColGameObject(unitId, ServerUnit.class); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } Unit carrier; try { carrier = serverPlayer.getOurFreeColGameObject(carrierId, Unit.class); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } @@ -129,10 +129,10 @@ public ChangeSet serverHandler(FreeColServer freeColServer, + unitId); } - Tile destinationTile = null; + Tile destinationTile; try { destinationTile = unit.getNeighbourTile(directionString); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } if (carrier.getTile() != destinationTile) { diff --git a/src/net/sf/freecol/common/networking/EmigrateUnitMessage.java b/src/net/sf/freecol/common/networking/EmigrateUnitMessage.java index 5cb87bee22..f3fb1cc152 100644 --- a/src/net/sf/freecol/common/networking/EmigrateUnitMessage.java +++ b/src/net/sf/freecol/common/networking/EmigrateUnitMessage.java @@ -55,6 +55,7 @@ public EmigrateUnitMessage(int slot) { * @param xr The {@code FreeColXMLReader} to read from. * @exception XMLStreamException if the stream is corrupt. */ + @SuppressWarnings("PMD.UnusedFormalParameter") public EmigrateUnitMessage(Game game, FreeColXMLReader xr) throws XMLStreamException { super(TAG, xr, SLOT_TAG); diff --git a/src/net/sf/freecol/common/networking/EquipForRoleMessage.java b/src/net/sf/freecol/common/networking/EquipForRoleMessage.java index 58b6309dff..73ce5248b9 100644 --- a/src/net/sf/freecol/common/networking/EquipForRoleMessage.java +++ b/src/net/sf/freecol/common/networking/EquipForRoleMessage.java @@ -95,7 +95,7 @@ public ChangeSet serverHandler(FreeColServer freeColServer, Unit unit; try { unit = serverPlayer.getOurFreeColGameObject(unitId, Unit.class); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } if (unit.isInEurope()) { diff --git a/src/net/sf/freecol/common/networking/FirstContactMessage.java b/src/net/sf/freecol/common/networking/FirstContactMessage.java index 52bca43d34..152eafce51 100644 --- a/src/net/sf/freecol/common/networking/FirstContactMessage.java +++ b/src/net/sf/freecol/common/networking/FirstContactMessage.java @@ -29,6 +29,7 @@ import net.sf.freecol.server.FreeColServer; import net.sf.freecol.server.ai.AIPlayer; import net.sf.freecol.server.model.ServerPlayer; +import java.util.logging.Level; /** @@ -65,6 +66,7 @@ public FirstContactMessage(Player player, Player other, Tile tile) { * @param xr The {@code FreeColXMLReader} to read from. * @exception XMLStreamException if the stream is corrupt. */ + @SuppressWarnings("PMD.UnusedFormalParameter") public FirstContactMessage(Game game, FreeColXMLReader xr) throws XMLStreamException { super(TAG, xr, PLAYER_TAG, OTHER_TAG, TILE_TAG, CAMPS_TAG, RESULT_TAG); @@ -104,15 +106,15 @@ public void clientHandler(FreeColClient freeColClient) { final int n = getSettlementCount(); if (player == null || player != freeColClient.getMyPlayer()) { - logger.warning("firstContact with bad player: " + player); + if (logger.isLoggable(Level.WARNING)) logger.warning("firstContact with bad player: " + player); return; } if (other == null || other == player || !other.isIndian()) { - logger.warning("firstContact with bad other player: " + other); + if (logger.isLoggable(Level.WARNING)) logger.warning("firstContact with bad other player: " + other); return; } if (tile != null && tile.getOwner() != other) { - logger.warning("firstContact with bad tile: " + tile); + if (logger.isLoggable(Level.WARNING)) logger.warning("firstContact with bad tile: " + tile); return; } @@ -133,9 +135,7 @@ public ChangeSet serverHandler(FreeColServer freeColServer, Player first = getPlayer(game); if (first == null) { return serverPlayer.clientError("Invalid player: " + playerId); - } else if (serverPlayer.getId().equals(playerId)) { - ; // OK - } else { + } else if (!serverPlayer.getId().equals(playerId)) { return serverPlayer.clientError("Not our player: " + playerId); } diff --git a/src/net/sf/freecol/common/networking/FountainOfYouthMessage.java b/src/net/sf/freecol/common/networking/FountainOfYouthMessage.java index 93331a703c..2dae248b16 100644 --- a/src/net/sf/freecol/common/networking/FountainOfYouthMessage.java +++ b/src/net/sf/freecol/common/networking/FountainOfYouthMessage.java @@ -26,6 +26,7 @@ import net.sf.freecol.common.model.Game; import net.sf.freecol.server.FreeColServer; import net.sf.freecol.server.ai.AIPlayer; +import java.util.logging.Level; /** @@ -53,6 +54,7 @@ public FountainOfYouthMessage(int migrants) { * @param xr The {@code FreeColXMLReader} to read from. * @exception XMLStreamException if the stream is corrupt. */ + @SuppressWarnings("PMD.UnusedFormalParameter") public FountainOfYouthMessage(Game game, FreeColXMLReader xr) throws XMLStreamException { super(TAG, xr, MIGRANTS_TAG); @@ -84,7 +86,7 @@ public void clientHandler(FreeColClient freeColClient) { final int n = getMigrants(); if (n <= 0) { - logger.warning("Invalid migrants attribute: " + n); + if (logger.isLoggable(Level.WARNING)) logger.warning("Invalid migrants attribute: " + n); return; } diff --git a/src/net/sf/freecol/common/networking/GameEndedMessage.java b/src/net/sf/freecol/common/networking/GameEndedMessage.java index 6f83c306fa..ad4f2f6ffb 100644 --- a/src/net/sf/freecol/common/networking/GameEndedMessage.java +++ b/src/net/sf/freecol/common/networking/GameEndedMessage.java @@ -58,6 +58,7 @@ public GameEndedMessage(Player winner, boolean highScore) { * @param xr The {@code FreeColXMLReader} to read from. * @exception XMLStreamException if the stream is corrupt. */ + @SuppressWarnings("PMD.UnusedFormalParameter") public GameEndedMessage(Game game, FreeColXMLReader xr) throws XMLStreamException { super(TAG, xr, WINNER_TAG, HIGH_SCORE_TAG); diff --git a/src/net/sf/freecol/common/networking/GameStateMessage.java b/src/net/sf/freecol/common/networking/GameStateMessage.java index 1a6ec63fad..4f59eca6ff 100644 --- a/src/net/sf/freecol/common/networking/GameStateMessage.java +++ b/src/net/sf/freecol/common/networking/GameStateMessage.java @@ -63,6 +63,7 @@ public GameStateMessage(ServerState serverState) { * exists at this point). * @param xr The {@code FreeColXMLReader} to read from. */ + @SuppressWarnings("PMD.UnusedFormalParameter") public GameStateMessage(Game game, FreeColXMLReader xr) { this(xr.getAttribute(STATE_TAG, ServerState.class, (ServerState)null)); } diff --git a/src/net/sf/freecol/common/networking/InciteMessage.java b/src/net/sf/freecol/common/networking/InciteMessage.java index b8d5ba8cb4..ef9aaf5731 100644 --- a/src/net/sf/freecol/common/networking/InciteMessage.java +++ b/src/net/sf/freecol/common/networking/InciteMessage.java @@ -117,14 +117,14 @@ public ChangeSet serverHandler(FreeColServer freeColServer, ServerUnit unit; try { unit = (ServerUnit)getUnit(serverPlayer); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } IndianSettlement is; try { is = getSettlement(unit); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } @@ -137,8 +137,9 @@ public ChangeSet serverHandler(FreeColServer freeColServer, return serverPlayer.clientError("Inciting against oneself!"); } else if (!enemy.isEuropean()) { return serverPlayer.clientError("Inciting against non-European!"); - } else if ((type = unit.getMoveType(is.getTile())) - != MoveType.ENTER_INDIAN_SETTLEMENT_WITH_MISSIONARY) { + } + type = unit.getMoveType(is.getTile()); + if (type != MoveType.ENTER_INDIAN_SETTLEMENT_WITH_MISSIONARY) { return serverPlayer.clientError("Unable to enter " + is.getName() + ": " + type.whyIllegal()); } diff --git a/src/net/sf/freecol/common/networking/IndianDemandMessage.java b/src/net/sf/freecol/common/networking/IndianDemandMessage.java index 300cb4763d..88e592ac9a 100644 --- a/src/net/sf/freecol/common/networking/IndianDemandMessage.java +++ b/src/net/sf/freecol/common/networking/IndianDemandMessage.java @@ -162,7 +162,7 @@ public ChangeSet serverHandler(FreeColServer freeColServer, + serverPlayer.getId()); } } - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } diff --git a/src/net/sf/freecol/common/networking/JoinColonyMessage.java b/src/net/sf/freecol/common/networking/JoinColonyMessage.java index 6cd0b273e3..8629be42eb 100644 --- a/src/net/sf/freecol/common/networking/JoinColonyMessage.java +++ b/src/net/sf/freecol/common/networking/JoinColonyMessage.java @@ -90,14 +90,14 @@ public ChangeSet serverHandler(FreeColServer freeColServer, Unit unit; try { unit = serverPlayer.getOurFreeColGameObject(unitId, Unit.class); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } Colony colony; try { colony = serverPlayer.getOurFreeColGameObject(colonyId, Colony.class); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } diff --git a/src/net/sf/freecol/common/networking/LearnSkillMessage.java b/src/net/sf/freecol/common/networking/LearnSkillMessage.java index 167671bc88..329cf4364b 100644 --- a/src/net/sf/freecol/common/networking/LearnSkillMessage.java +++ b/src/net/sf/freecol/common/networking/LearnSkillMessage.java @@ -96,14 +96,14 @@ public ChangeSet serverHandler(FreeColServer freeColServer, ServerUnit unit; try { unit = serverPlayer.getOurFreeColGameObject(unitId, ServerUnit.class); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } Tile tile; try { tile = unit.getNeighbourTile(directionString); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } diff --git a/src/net/sf/freecol/common/networking/LoadGoodsMessage.java b/src/net/sf/freecol/common/networking/LoadGoodsMessage.java index 411e1d297a..2571121987 100644 --- a/src/net/sf/freecol/common/networking/LoadGoodsMessage.java +++ b/src/net/sf/freecol/common/networking/LoadGoodsMessage.java @@ -110,7 +110,7 @@ public ChangeSet serverHandler(FreeColServer freeColServer, Unit carrier; try { carrier = serverPlayer.getOurFreeColGameObject(carrierId, Unit.class); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } if (!carrier.canCarryGoods()) { diff --git a/src/net/sf/freecol/common/networking/LoginMessage.java b/src/net/sf/freecol/common/networking/LoginMessage.java index aef46d34fa..aeb176faf1 100644 --- a/src/net/sf/freecol/common/networking/LoginMessage.java +++ b/src/net/sf/freecol/common/networking/LoginMessage.java @@ -206,23 +206,23 @@ private ChangeSet preGameLogin(FreeColServer freeColServer, Nation nation; ChangeSet ret; - if ((serverGame = freeColServer.waitForGame()) == null) { + serverGame = freeColServer.waitForGame(); + if (serverGame == null) { // No game found ret = ChangeSet.clientError((Player)null, StringTemplate.template("server.timeOut")); - - } else if ((nation = serverGame.getVacantNation()) == null) { - // No nation available - ret = ChangeSet.clientError((Player)null, - StringTemplate.template("server.maximumPlayers")); - - } else if (getPlayer(serverGame) != null) { - // Can not use the same name as existing player - ret = ChangeSet.clientError((Player)null, - StringTemplate.template("server.userNameInUse") - .addName("%name%", userName)); - } else { + nation = serverGame.getVacantNation(); + if (nation == null) { + // No nation available + ret = ChangeSet.clientError((Player)null, + StringTemplate.template("server.maximumPlayers")); + } else if (getPlayer(serverGame) != null) { + // Can not use the same name as existing player + ret = ChangeSet.clientError((Player)null, + StringTemplate.template("server.userNameInUse") + .addName("%name%", userName)); + } else { // OK, make a new player and complete initialization... ServerPlayer serverPlayer = new ServerPlayer(serverGame, connection); serverPlayer.initialize(serverGame, @@ -258,6 +258,7 @@ private ChangeSet preGameLogin(FreeColServer freeColServer, serverGame)); serverGame.sendToOthers(serverPlayer, ret); + } } return ret; } @@ -280,55 +281,56 @@ private ChangeSet loadGameLogin(FreeColServer freeColServer, // Trying to start a map, see BR#2976 -> IR#217 ret = ChangeSet.clientError((Player)null, StringTemplate.template("error.mapEditorGame")); - - } else if ((serverGame = freeColServer.getGame()) == null) { - // No game found - ret = ChangeSet.clientError((Player)null, - StringTemplate.template("server.noSuchGame")); - - } else if ((present = getPlayer(serverGame)) == null) { - // Player not present - ret = ChangeSet.clientError((Player)null, - StringTemplate.template("server.userNameNotPresent") - .addName("%name%", userName) - .addName("%names%", - transform(serverGame.getLiveEuropeanPlayers(), - alwaysTrue(), Player::getName, - Collectors.joining(", ")))); - - } else if (present.isConnected()) { - // Another player already connected on the name - ret = ChangeSet.clientError((Player)null, - StringTemplate.template("server.userNameInUse") - .addName("%name%", userName)); - - } else if (present.isAI()) { - // Should not connect to AI - ret = ChangeSet.clientError((Player)null, - StringTemplate.template("server.userNameInUse") - .addName("%name%", userName)); - } else { - // Found the player - present.setConnection(connection); - - // Ensure there is a current player. - if (serverGame.getCurrentPlayer() == null) { - serverGame.setCurrentPlayer(present); + serverGame = freeColServer.getGame(); + if (serverGame == null) { + // No game found + ret = ChangeSet.clientError((Player)null, + StringTemplate.template("server.noSuchGame")); + } else { + present = getPlayer(serverGame); + if (present == null) { + // Player not present + ret = ChangeSet.clientError((Player)null, + StringTemplate.template("server.userNameNotPresent") + .addName("%name%", userName) + .addName("%names%", + transform(serverGame.getLiveEuropeanPlayers(), + alwaysTrue(), Player::getName, + Collectors.joining(", ")))); + } else if (present.isConnected()) { + // Another player already connected on the name + ret = ChangeSet.clientError((Player)null, + StringTemplate.template("server.userNameInUse") + .addName("%name%", userName)); + } else if (present.isAI()) { + // Should not connect to AI + ret = ChangeSet.clientError((Player)null, + StringTemplate.template("server.userNameInUse") + .addName("%name%", userName)); + } else { + // Found the player + present.setConnection(connection); + + // Ensure there is a current player. + if (serverGame.getCurrentPlayer() == null) { + serverGame.setCurrentPlayer(present); + } + + // Add the connection, send back the game. + freeColServer.addPlayerConnection(connection); + connection.setWriteScope(FreeColXMLWriter.WriteScope + .toClient(present)); + ret = ChangeSet.simpleChange(present, + new LoginMessage(present, userName, + present.getNationId(), + getVersion(), + freeColServer.getServerState(), + freeColServer.getSinglePlayer(), + serverGame.getCurrentPlayer() == present, + serverGame)); + } } - - // Add the connection, send back the game. - freeColServer.addPlayerConnection(connection); - connection.setWriteScope(FreeColXMLWriter.WriteScope - .toClient(present)); - ret = ChangeSet.simpleChange(present, - new LoginMessage(present, userName, - present.getNationId(), - getVersion(), - freeColServer.getServerState(), - freeColServer.getSinglePlayer(), - serverGame.getCurrentPlayer() == present, - serverGame)); } return ret; } @@ -347,27 +349,27 @@ private ChangeSet inGameLogin(FreeColServer freeColServer, Player present; ChangeSet ret; - if ((serverGame = freeColServer.getGame()) == null) { + serverGame = freeColServer.getGame(); + if (serverGame == null) { ret = ChangeSet.clientError((Player)null, StringTemplate.template("server.noSuchGame")); - - } else if ((present = getPlayer(serverGame)) == null) { - // Player not present - ret = ChangeSet.clientError((Player)null, - StringTemplate.template("server.userNameNotPresent") - .addName("%name%", userName) - .addName("%names%", - transform(serverGame.getLiveEuropeanPlayers(), - alwaysTrue(), Player::getName, - Collectors.joining(", ")))); - - } else if (!present.isAI() && present.isConnected()) { - // Another human player already connected on the name - ret = ChangeSet.clientError((Player)null, - StringTemplate.template("server.userNameInUse") - .addName("%name%", userName)); - } else { + present = getPlayer(serverGame); + if (present == null) { + // Player not present + ret = ChangeSet.clientError((Player)null, + StringTemplate.template("server.userNameNotPresent") + .addName("%name%", userName) + .addName("%names%", + transform(serverGame.getLiveEuropeanPlayers(), + alwaysTrue(), Player::getName, + Collectors.joining(", ")))); + } else if (!present.isAI() && present.isConnected()) { + // Another human player already connected on the name + ret = ChangeSet.clientError((Player)null, + StringTemplate.template("server.userNameInUse") + .addName("%name%", userName)); + } else { // Join allowed, including over an AI if (present.isAI()) serverGame.changeAI(present, false); @@ -385,6 +387,7 @@ private ChangeSet inGameLogin(FreeColServer freeColServer, freeColServer.getSinglePlayer(), serverGame.getCurrentPlayer() == present, serverGame)); + } } return ret; } diff --git a/src/net/sf/freecol/common/networking/LogoutMessage.java b/src/net/sf/freecol/common/networking/LogoutMessage.java index 9167a69336..c88e000240 100644 --- a/src/net/sf/freecol/common/networking/LogoutMessage.java +++ b/src/net/sf/freecol/common/networking/LogoutMessage.java @@ -31,6 +31,7 @@ import net.sf.freecol.server.ai.AIPlayer; import net.sf.freecol.server.model.ServerPlayer; import net.sf.freecol.server.model.Session; +import java.util.logging.Level; /** @@ -63,6 +64,7 @@ public LogoutMessage(Player player, LogoutReason reason) { * @param xr The {@code FreeColXMLReader} to read from. * @exception XMLStreamException if the stream is corrupt. */ + @SuppressWarnings("PMD.UnusedFormalParameter") public LogoutMessage(Game game, FreeColXMLReader xr) throws XMLStreamException { super(TAG, xr, PLAYER_TAG, REASON_TAG); @@ -110,7 +112,7 @@ public void clientHandler(FreeColClient freeColClient) { public ChangeSet serverHandler(FreeColServer freeColServer, ServerPlayer serverPlayer) { if (serverPlayer == null) return null; - logger.info("Handling logout by " + serverPlayer.getName()); + if (logger.isLoggable(Level.INFO)) logger.info("Handling logout by " + serverPlayer.getName()); LogoutReason reason = getReason(); ChangeSet cs = null; diff --git a/src/net/sf/freecol/common/networking/LootCargoMessage.java b/src/net/sf/freecol/common/networking/LootCargoMessage.java index 1e6c176802..166cfb5fa9 100644 --- a/src/net/sf/freecol/common/networking/LootCargoMessage.java +++ b/src/net/sf/freecol/common/networking/LootCargoMessage.java @@ -161,7 +161,7 @@ public ChangeSet serverHandler(FreeColServer freeColServer, Unit winner; try { winner = getWinner(game); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } // Do not check the defender identifier, as it might have diff --git a/src/net/sf/freecol/common/networking/Message.java b/src/net/sf/freecol/common/networking/Message.java index c1f54e38ae..23983ea5bc 100644 --- a/src/net/sf/freecol/common/networking/Message.java +++ b/src/net/sf/freecol/common/networking/Message.java @@ -273,7 +273,9 @@ protected Boolean getBooleanAttribute(String key, Boolean defaultValue) { if (hasAttribute(key)) { try { return Boolean.valueOf(getStringAttribute(key)); - } catch (NumberFormatException nfe) {} + } catch (NumberFormatException nfe) { + if (logger.isLoggable(Level.FINE)) logger.log(Level.FINE, "Invalid boolean attribute: " + key, nfe); + } } return defaultValue; } @@ -289,7 +291,9 @@ protected Integer getIntegerAttribute(String key, int defaultValue) { if (hasAttribute(key)) { try { return Integer.valueOf(getStringAttribute(key)); - } catch (NumberFormatException nfe) {} + } catch (NumberFormatException nfe) { + if (logger.isLoggable(Level.FINE)) logger.log(Level.FINE, "Invalid integer attribute: " + key, nfe); + } } return defaultValue; } @@ -311,8 +315,8 @@ protected > T getEnumAttribute(String key, String kv = upCase(getStringAttribute(key)); try { result = Enum.valueOf(returnClass, kv); - } catch (Exception e) { - logger.warning("Not a " + defaultValue.getClass().getName() + } catch (IllegalArgumentException e) { + if (logger.isLoggable(Level.WARNING)) logger.warning("Not a " + defaultValue.getClass().getName() + ": " + kv); } } @@ -377,7 +381,7 @@ protected void setStringAttributes(List attributes) { * * @param attributes An array of alternating key,value pairs. */ - protected void setStringAttributes(String[] attributes) { + protected void setStringAttributes(String... attributes) { for (int i = 0; i < attributes.length; i += 2) { if (attributes[i+1] != null) { setStringAttribute(attributes[i], attributes[i+1]); @@ -423,7 +427,7 @@ protected void setArrayAttributes(List attributes) { * * @param attributes The array of attributes. */ - protected void setArrayAttributes(String[] attributes) { + protected void setArrayAttributes(String... attributes) { if (attributes != null) { for (int i = 0; i < attributes.length; i++) { setStringAttribute(FreeColObject.arrayKey(i), attributes[i]); @@ -464,7 +468,9 @@ protected List getChildren(Class returnClass) { for (FreeColObject fco : getChildren()) { try { ret.add(returnClass.cast(fco)); - } catch (ClassCastException cce) {} + } catch (ClassCastException cce) { + logger.log(Level.FINE, "Child cast failed.", cce); + } } return ret; } @@ -629,7 +635,7 @@ protected void expected(String wanted, String got) public static Message read(Game game, FreeColXMLReader xr) throws FreeColException { final String tag = xr.getLocalName(); - Message ret = null; + Message ret; Constructor mb = builders.get(tag); if (mb == null) { final String className = "net.sf.freecol.common.networking." diff --git a/src/net/sf/freecol/common/networking/MissionaryMessage.java b/src/net/sf/freecol/common/networking/MissionaryMessage.java index 516f16de8f..90f2ca59f8 100644 --- a/src/net/sf/freecol/common/networking/MissionaryMessage.java +++ b/src/net/sf/freecol/common/networking/MissionaryMessage.java @@ -101,14 +101,14 @@ public ChangeSet serverHandler(FreeColServer freeColServer, ServerUnit unit; try { unit = serverPlayer.getOurFreeColGameObject(unitId, ServerUnit.class); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } Tile tile; try { tile = unit.getNeighbourTile(directionString); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } diff --git a/src/net/sf/freecol/common/networking/MoveMessage.java b/src/net/sf/freecol/common/networking/MoveMessage.java index 1749b02ad5..07aaff9b93 100644 --- a/src/net/sf/freecol/common/networking/MoveMessage.java +++ b/src/net/sf/freecol/common/networking/MoveMessage.java @@ -96,14 +96,14 @@ public ChangeSet serverHandler(FreeColServer freeColServer, try { unit = serverPlayer.getOurFreeColGameObject(unitId, ServerUnit.class); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } Tile tile; try { tile = unit.getNeighbourTile(directionString); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } diff --git a/src/net/sf/freecol/common/networking/MoveToMessage.java b/src/net/sf/freecol/common/networking/MoveToMessage.java index b729668c2c..8b2a404b85 100644 --- a/src/net/sf/freecol/common/networking/MoveToMessage.java +++ b/src/net/sf/freecol/common/networking/MoveToMessage.java @@ -93,7 +93,7 @@ public ChangeSet serverHandler(FreeColServer freeColServer, Unit unit; try { unit = serverPlayer.getOurFreeColGameObject(unitId, Unit.class); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } diff --git a/src/net/sf/freecol/common/networking/NativeGiftMessage.java b/src/net/sf/freecol/common/networking/NativeGiftMessage.java index 5af635b81d..d7734f4e07 100644 --- a/src/net/sf/freecol/common/networking/NativeGiftMessage.java +++ b/src/net/sf/freecol/common/networking/NativeGiftMessage.java @@ -99,14 +99,14 @@ public ChangeSet serverHandler(FreeColServer freeColServer, Unit unit; try { unit = serverPlayer.getOurFreeColGameObject(unitId, Unit.class); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } Colony colony; try { colony = unit.getAdjacentSettlement(colonyId, Colony.class); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } diff --git a/src/net/sf/freecol/common/networking/NetworkReplyObject.java b/src/net/sf/freecol/common/networking/NetworkReplyObject.java index d0d9b73453..37694b9568 100644 --- a/src/net/sf/freecol/common/networking/NetworkReplyObject.java +++ b/src/net/sf/freecol/common/networking/NetworkReplyObject.java @@ -20,6 +20,8 @@ package net.sf.freecol.common.networking; import java.util.concurrent.TimeoutException; +import java.util.logging.Level; +import java.util.logging.Logger; /** * Class for storing a network response. If the response has not been @@ -28,6 +30,8 @@ */ public class NetworkReplyObject { + private static final Logger logger = Logger.getLogger(NetworkReplyObject.class.getName()); + private static int ONE_SECOND = 1000; // 1000ms /** A unique identifier for the message to wait for. */ @@ -83,7 +87,10 @@ public synchronized Object getResponse(long timeout) throws TimeoutException { } try { wait(ONE_SECOND); - } catch (InterruptedException ie) {} + } catch (InterruptedException ie) { + Thread.currentThread().interrupt(); + logger.log(Level.FINE, "Interrupted while waiting for response.", ie); + } } return this.response; } diff --git a/src/net/sf/freecol/common/networking/NewLandNameMessage.java b/src/net/sf/freecol/common/networking/NewLandNameMessage.java index cdd84f4b67..ade90d76ed 100644 --- a/src/net/sf/freecol/common/networking/NewLandNameMessage.java +++ b/src/net/sf/freecol/common/networking/NewLandNameMessage.java @@ -108,7 +108,7 @@ public ChangeSet serverHandler(FreeColServer freeColServer, Unit unit; try { unit = getUnit(serverPlayer); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } diff --git a/src/net/sf/freecol/common/networking/NewRegionNameMessage.java b/src/net/sf/freecol/common/networking/NewRegionNameMessage.java index ebf6b7a834..edbc230baa 100644 --- a/src/net/sf/freecol/common/networking/NewRegionNameMessage.java +++ b/src/net/sf/freecol/common/networking/NewRegionNameMessage.java @@ -129,7 +129,7 @@ public ChangeSet serverHandler(FreeColServer freeColServer, Unit unit; try { unit = getUnit(serverPlayer); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } diff --git a/src/net/sf/freecol/common/networking/NewTurnMessage.java b/src/net/sf/freecol/common/networking/NewTurnMessage.java index 40e3ef725f..3d0f6898e0 100644 --- a/src/net/sf/freecol/common/networking/NewTurnMessage.java +++ b/src/net/sf/freecol/common/networking/NewTurnMessage.java @@ -27,6 +27,7 @@ import net.sf.freecol.common.model.Turn; import net.sf.freecol.server.FreeColServer; import net.sf.freecol.server.ai.AIPlayer; +import java.util.logging.Level; /** @@ -55,6 +56,7 @@ public NewTurnMessage(Turn turn) { * @param xr The {@code FreeColXMLReader} to read from. * @exception XMLStreamException if the stream is corrupt. */ + @SuppressWarnings("PMD.UnusedFormalParameter") public NewTurnMessage(Game game, FreeColXMLReader xr) throws XMLStreamException { super(TAG, xr, TURN_TAG); @@ -85,7 +87,7 @@ public void clientHandler(FreeColClient freeColClient) { final int turn = getTurnNumber(); if (turn < 0) { - logger.warning("Invalid turn for newTurn: " + if (logger.isLoggable(Level.WARNING)) logger.warning("Invalid turn for newTurn: " + Integer.toString(turn) ); return; } diff --git a/src/net/sf/freecol/common/networking/PartialMessage.java b/src/net/sf/freecol/common/networking/PartialMessage.java index 9f5004447f..75b97fd67e 100644 --- a/src/net/sf/freecol/common/networking/PartialMessage.java +++ b/src/net/sf/freecol/common/networking/PartialMessage.java @@ -30,6 +30,7 @@ import net.sf.freecol.common.model.Game; import net.sf.freecol.server.FreeColServer; import net.sf.freecol.server.ai.AIPlayer; +import java.util.logging.Level; /** @@ -58,6 +59,7 @@ public PartialMessage(Map map) { * @param xr The {@code FreeColXMLReader} to read from. * @exception XMLStreamException if the stream is corrupt. */ + @SuppressWarnings("PMD.UnusedFormalParameter") public PartialMessage(Game game, FreeColXMLReader xr) throws XMLStreamException { super(TAG, xr.getAllAttributes()); @@ -107,7 +109,7 @@ public void clientHandler(FreeColClient freeColClient) { } FreeColGameObject fcgo = game.getFreeColGameObject(id); if (fcgo == null) { - logger.warning("Partial update of missing object: " + id); + if (logger.isLoggable(Level.WARNING)) logger.warning("Partial update of missing object: " + id); return; } diff --git a/src/net/sf/freecol/common/networking/PayArrearsMessage.java b/src/net/sf/freecol/common/networking/PayArrearsMessage.java index 540b4baa5d..b3b86ead11 100644 --- a/src/net/sf/freecol/common/networking/PayArrearsMessage.java +++ b/src/net/sf/freecol/common/networking/PayArrearsMessage.java @@ -54,6 +54,7 @@ public PayArrearsMessage(GoodsType type) { * @param xr The {@code FreeColXMLReader} to read from. * @exception XMLStreamException if the stream is corrupt. */ + @SuppressWarnings("PMD.UnusedFormalParameter") public PayArrearsMessage(Game game, FreeColXMLReader xr) throws XMLStreamException { super(TAG, xr, GOODS_TYPE_TAG); diff --git a/src/net/sf/freecol/common/networking/PayForBuildingMessage.java b/src/net/sf/freecol/common/networking/PayForBuildingMessage.java index 172c0019ad..c79f5bf041 100644 --- a/src/net/sf/freecol/common/networking/PayForBuildingMessage.java +++ b/src/net/sf/freecol/common/networking/PayForBuildingMessage.java @@ -87,7 +87,7 @@ public ChangeSet serverHandler(FreeColServer freeColServer, Colony colony; try { colony = serverPlayer.getOurFreeColGameObject(colonyId, Colony.class); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } diff --git a/src/net/sf/freecol/common/networking/PutOutsideColonyMessage.java b/src/net/sf/freecol/common/networking/PutOutsideColonyMessage.java index c74d3fd984..25745da7f9 100644 --- a/src/net/sf/freecol/common/networking/PutOutsideColonyMessage.java +++ b/src/net/sf/freecol/common/networking/PutOutsideColonyMessage.java @@ -87,7 +87,7 @@ public ChangeSet serverHandler(FreeColServer freeColServer, Unit unit; try { unit = serverPlayer.getOurFreeColGameObject(unitId, Unit.class); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } if (!unit.hasTile()) { diff --git a/src/net/sf/freecol/common/networking/ReadyMessage.java b/src/net/sf/freecol/common/networking/ReadyMessage.java index 42b7b59cf6..8c4925edf3 100644 --- a/src/net/sf/freecol/common/networking/ReadyMessage.java +++ b/src/net/sf/freecol/common/networking/ReadyMessage.java @@ -57,6 +57,7 @@ public ReadyMessage(Player player, boolean ready) { * @param xr The {@code FreeColXMLReader} to read from. * @exception XMLStreamException if the stream is corrupt. */ + @SuppressWarnings("PMD.UnusedFormalParameter") public ReadyMessage(Game game, FreeColXMLReader xr) throws XMLStreamException { super(TAG, xr, PLAYER_TAG, VALUE_TAG); diff --git a/src/net/sf/freecol/common/networking/RearrangeColonyMessage.java b/src/net/sf/freecol/common/networking/RearrangeColonyMessage.java index d3ddc1254d..82e7a2d915 100644 --- a/src/net/sf/freecol/common/networking/RearrangeColonyMessage.java +++ b/src/net/sf/freecol/common/networking/RearrangeColonyMessage.java @@ -257,7 +257,7 @@ public ChangeSet serverHandler(FreeColServer freeColServer, Colony colony; try { colony = serverPlayer.getOurFreeColGameObject(colonyId, Colony.class); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } diff --git a/src/net/sf/freecol/common/networking/ReceivingThread.java b/src/net/sf/freecol/common/networking/ReceivingThread.java index c3a545b0ca..42246afa69 100644 --- a/src/net/sf/freecol/common/networking/ReceivingThread.java +++ b/src/net/sf/freecol/common/networking/ReceivingThread.java @@ -80,7 +80,7 @@ public void run() { try { reply = this.conn.handle(this.query); } catch (FreeColException fce) { - logger.log(Level.WARNING, getName() + ": handler fail", fce); + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, getName() + ": handler fail", fce); return; } @@ -88,9 +88,9 @@ public void run() { : reply.getType(); try { this.conn.sendMessage(new ReplyMessage(this.replyId, reply)); - logger.log(Level.FINEST, getName() + " -> " + replyTag); + if (logger.isLoggable(Level.FINEST)) logger.log(Level.FINEST, getName() + " -> " + replyTag); } catch (FreeColException|IOException|XMLStreamException ex) { - logger.log(Level.WARNING, getName() + " -> " + replyTag + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, getName() + " -> " + replyTag + " failed", ex); } } @@ -128,16 +128,16 @@ public void run() { try { reply = this.conn.handle(this.message); } catch (FreeColException fce) { - logger.log(Level.WARNING, getName() + ": handler fail", fce); + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, getName() + ": handler fail", fce); return; } final String outTag = (reply == null) ? "null" : reply.getType(); try { this.conn.sendMessage(reply); - logger.log(Level.FINEST, getName() + " -> " + outTag); + if (logger.isLoggable(Level.FINEST)) logger.log(Level.FINEST, getName() + " -> " + outTag); } catch (FreeColException|IOException|XMLStreamException ex) { - logger.log(Level.WARNING, getName() + " -> " + outTag + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, getName() + " -> " + outTag + " failed", ex); } } @@ -243,7 +243,7 @@ private boolean stopThread() { */ public void askToStop(String reason) { if (stopThread()) { - logger.info(getName() + ": stopped receiving thread: " + reason); + if (logger.isLoggable(Level.INFO)) logger.info(getName() + ": stopped receiving thread: " + reason); } } @@ -295,12 +295,12 @@ private Thread messageUpdate(final Message message) { */ private void listen() throws IOException, SAXException, XMLStreamException { String tag; - int replyId = -1; + int replyId; try { tag = this.connection.startListen(); } catch (XMLStreamException xse) { if (!shouldRun()) return; // Connection shutdown, fail expected - logger.log(Level.WARNING, getName() + ": listen fail", xse); + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, getName() + ": listen fail", xse); tag = DisconnectMessage.TAG; } @@ -322,13 +322,13 @@ private void listen() throws IOException, SAXException, XMLStreamException { Message rm; try { rm = this.connection.reader(); - } catch (Exception ex) { + } catch (FreeColException | XMLStreamException ex) { rm = null; - logger.log(Level.WARNING, getName() + ": reply fail", ex); + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, getName() + ": reply fail", ex); } NetworkReplyObject nro = this.waitingThreads.remove(replyId); if (nro == null) { - logger.warning(getName() + ": did not find reply " + replyId); + if (logger.isLoggable(Level.WARNING)) logger.warning(getName() + ": did not find reply " + replyId); } else { nro.setResponse(rm); } @@ -338,13 +338,13 @@ private void listen() throws IOException, SAXException, XMLStreamException { // A question. Build a thread to handle it and send a reply. replyId = this.connection.getReplyId(); - Message m = null; + Message m; try { m = this.connection.reader(); assert m instanceof QuestionMessage; t = messageQuestion((QuestionMessage)m, replyId); } catch (FreeColException fce) { - logger.log(Level.WARNING, "No reader for " + replyId, fce); + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "No reader for " + replyId, fce); t = null; } break; @@ -355,8 +355,8 @@ private void listen() throws IOException, SAXException, XMLStreamException { try { t = messageUpdate(this.connection.reader()); - } catch (Exception ex) { - logger.log(Level.FINEST, getName() + ": fail", ex); + } catch (FreeColException | XMLStreamException ex) { + if (logger.isLoggable(Level.FINEST)) logger.log(Level.FINEST, getName() + ": fail", ex); askToStop("listen-update-fail"); } break; @@ -387,13 +387,13 @@ public void run() { timesFailed = 0; } catch (SAXException|XMLStreamException ex) { if (!shouldRun()) break; - logger.log(Level.WARNING, getName() + ": XML fail", ex); + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, getName() + ": XML fail", ex); if (++timesFailed > MAXIMUM_RETRIES) { disconnect(); } } catch (IOException ioe) { if (!shouldRun()) break; - logger.log(Level.WARNING, getName() + ": IO fail", ioe); + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, getName() + ": IO fail", ioe); disconnect(); } } diff --git a/src/net/sf/freecol/common/networking/RenameMessage.java b/src/net/sf/freecol/common/networking/RenameMessage.java index 9f7834a432..adc2147336 100644 --- a/src/net/sf/freecol/common/networking/RenameMessage.java +++ b/src/net/sf/freecol/common/networking/RenameMessage.java @@ -90,7 +90,7 @@ public ChangeSet serverHandler(FreeColServer freeColServer, FreeColGameObject fcgo; try { fcgo = serverPlayer.getOurFreeColGameObject(nameableId, FreeColGameObject.class); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } if (!(fcgo instanceof Nameable)) { diff --git a/src/net/sf/freecol/common/networking/ScoutIndianSettlementMessage.java b/src/net/sf/freecol/common/networking/ScoutIndianSettlementMessage.java index eb4bb63bb1..0cd26f0d0b 100644 --- a/src/net/sf/freecol/common/networking/ScoutIndianSettlementMessage.java +++ b/src/net/sf/freecol/common/networking/ScoutIndianSettlementMessage.java @@ -97,7 +97,7 @@ public ChangeSet serverHandler(FreeColServer freeColServer, ServerUnit unit; try { unit = serverPlayer.getOurFreeColGameObject(unitId, ServerUnit.class); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } if (!unit.hasAbility(Ability.SPEAK_WITH_CHIEF)) { @@ -108,7 +108,7 @@ public ChangeSet serverHandler(FreeColServer freeColServer, Tile tile; try { tile = unit.getNeighbourTile(directionString); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } diff --git a/src/net/sf/freecol/common/networking/ScoutSpeakToChiefMessage.java b/src/net/sf/freecol/common/networking/ScoutSpeakToChiefMessage.java index bae8671913..19a18a95ce 100644 --- a/src/net/sf/freecol/common/networking/ScoutSpeakToChiefMessage.java +++ b/src/net/sf/freecol/common/networking/ScoutSpeakToChiefMessage.java @@ -124,7 +124,7 @@ public ChangeSet serverHandler(FreeColServer freeColServer, ServerUnit unit; try { unit = serverPlayer.getOurFreeColGameObject(unitId, ServerUnit.class); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } if (!unit.hasAbility(Ability.SPEAK_WITH_CHIEF)) { @@ -136,7 +136,7 @@ public ChangeSet serverHandler(FreeColServer freeColServer, try { is = unit.getAdjacentSettlement(settlementId, IndianSettlement.class); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } diff --git a/src/net/sf/freecol/common/networking/ServerAPI.java b/src/net/sf/freecol/common/networking/ServerAPI.java index 47b597ef73..5a32a0554c 100644 --- a/src/net/sf/freecol/common/networking/ServerAPI.java +++ b/src/net/sf/freecol/common/networking/ServerAPI.java @@ -146,7 +146,7 @@ public boolean isConnected() { private Connection check(String operation, String type) { final Connection c = getConnection(); if (c == null) { - logger.log(Level.WARNING, "Not connected, did not " + operation + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Not connected, did not " + operation + ": " + type); } return c; diff --git a/src/net/sf/freecol/common/networking/ServerInfoMessage.java b/src/net/sf/freecol/common/networking/ServerInfoMessage.java index 57e9b427fa..80b79fcce9 100644 --- a/src/net/sf/freecol/common/networking/ServerInfoMessage.java +++ b/src/net/sf/freecol/common/networking/ServerInfoMessage.java @@ -67,7 +67,8 @@ protected ServerInfoMessage(String tag, ServerInfo si) { * @param xr The {@code FreeColXMLReader} to read from. * @exception XMLStreamException if there is a problem reading the stream. */ - public ServerInfoMessage(String tag, @SuppressWarnings("unused") Game game, + @SuppressWarnings("PMD.UnusedFormalParameter") + public ServerInfoMessage(String tag, Game game, FreeColXMLReader xr) throws XMLStreamException { super(tag, xr, NAME_TAG, ADDRESS_TAG, PORT_TAG, SLOTS_AVAILABLE_TAG, CURRENTLY_PLAYING_TAG, IS_GAME_STARTED_TAG, VERSION_TAG, diff --git a/src/net/sf/freecol/common/networking/SetAIMessage.java b/src/net/sf/freecol/common/networking/SetAIMessage.java index a1156c5cb2..f794c4f0d1 100644 --- a/src/net/sf/freecol/common/networking/SetAIMessage.java +++ b/src/net/sf/freecol/common/networking/SetAIMessage.java @@ -56,6 +56,7 @@ public SetAIMessage(Player player, boolean ai) { * @param xr A {@code FreeColXMLReader} to read from. * @exception XMLStreamException if the stream is corrupt. */ + @SuppressWarnings("PMD.UnusedFormalParameter") public SetAIMessage(Game game, FreeColXMLReader xr) throws XMLStreamException { super(TAG, xr, PLAYER_TAG, AI_TAG); diff --git a/src/net/sf/freecol/common/networking/SetAvailableMessage.java b/src/net/sf/freecol/common/networking/SetAvailableMessage.java index 0c5561efba..49278918e1 100644 --- a/src/net/sf/freecol/common/networking/SetAvailableMessage.java +++ b/src/net/sf/freecol/common/networking/SetAvailableMessage.java @@ -59,6 +59,7 @@ public SetAvailableMessage(Nation nation, NationState state) { * @param xr The {@code FreeColXMLReader} to read from. * @exception XMLStreamException if the stream is corrupt. */ + @SuppressWarnings("PMD.UnusedFormalParameter") public SetAvailableMessage(Game game, FreeColXMLReader xr) throws XMLStreamException { super(TAG, xr, NATION_TAG, STATE_TAG); diff --git a/src/net/sf/freecol/common/networking/SetBuildQueueMessage.java b/src/net/sf/freecol/common/networking/SetBuildQueueMessage.java index fe01649490..f544f43e4e 100644 --- a/src/net/sf/freecol/common/networking/SetBuildQueueMessage.java +++ b/src/net/sf/freecol/common/networking/SetBuildQueueMessage.java @@ -138,14 +138,14 @@ public ChangeSet serverHandler(FreeColServer freeColServer, Colony colony; try { colony = getColony(serverPlayer); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } List buildQueue; try { buildQueue = getQueue(spec); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } diff --git a/src/net/sf/freecol/common/networking/SetColorMessage.java b/src/net/sf/freecol/common/networking/SetColorMessage.java index 747e044c3b..88dbf6d3f7 100644 --- a/src/net/sf/freecol/common/networking/SetColorMessage.java +++ b/src/net/sf/freecol/common/networking/SetColorMessage.java @@ -20,6 +20,8 @@ package net.sf.freecol.common.networking; import java.awt.Color; +import java.util.logging.Level; +import java.util.logging.Logger; import javax.xml.stream.XMLStreamException; @@ -37,6 +39,8 @@ */ public class SetColorMessage extends AttributeMessage { + private static final Logger logger = Logger.getLogger(SetColorMessage.class.getName()); + public static final String TAG = "setColor"; private static final String COLOR_TAG = "color"; private static final String NATION_TAG = "nation"; @@ -60,6 +64,7 @@ public SetColorMessage(Nation nation, Color color) { * @param xr The {@code FreeColXMLReader} to read from. * @exception XMLStreamException if the stream is corrupt. */ + @SuppressWarnings("PMD.UnusedFormalParameter") public SetColorMessage(Game game, FreeColXMLReader xr) throws XMLStreamException { super(TAG, xr, NATION_TAG, COLOR_TAG); @@ -85,11 +90,11 @@ public void clientHandler(FreeColClient freeColClient) { final Color color = getColor(); if (nation == null) { - logger.warning("Invalid nation: " + toString()); + if (logger.isLoggable(Level.WARNING)) logger.warning("Invalid nation: " + toString()); return; } if (color == null) { - logger.warning("Invalid color: " + toString()); + if (logger.isLoggable(Level.WARNING)) logger.warning("Invalid color: " + toString()); return; } @@ -143,7 +148,9 @@ public Color getColor() { try { int rgb = getIntegerAttribute(COLOR_TAG, 0); color = new Color(rgb); - } catch (NumberFormatException nfe) {} + } catch (NumberFormatException nfe) { + logger.log(Level.FINE, "Invalid set-color value.", nfe); + } return color; } } diff --git a/src/net/sf/freecol/common/networking/SetCurrentPlayerMessage.java b/src/net/sf/freecol/common/networking/SetCurrentPlayerMessage.java index 1d72444389..f7972fe7f2 100644 --- a/src/net/sf/freecol/common/networking/SetCurrentPlayerMessage.java +++ b/src/net/sf/freecol/common/networking/SetCurrentPlayerMessage.java @@ -55,6 +55,7 @@ public SetCurrentPlayerMessage(Player player) { * @param xr The {@code FreeColXMLReader} to read from. * @exception XMLStreamException if the stream is corrupt. */ + @SuppressWarnings("PMD.UnusedFormalParameter") public SetCurrentPlayerMessage(Game game, FreeColXMLReader xr) throws XMLStreamException { super(TAG, xr, PLAYER_TAG); diff --git a/src/net/sf/freecol/common/networking/SetCurrentStopMessage.java b/src/net/sf/freecol/common/networking/SetCurrentStopMessage.java index 9d05251f3f..4400a08170 100644 --- a/src/net/sf/freecol/common/networking/SetCurrentStopMessage.java +++ b/src/net/sf/freecol/common/networking/SetCurrentStopMessage.java @@ -84,7 +84,7 @@ public ChangeSet serverHandler(FreeColServer freeColServer, ServerUnit serverUnit; try { serverUnit = serverPlayer.getOurFreeColGameObject(unitId, ServerUnit.class); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } TradeRoute tr = serverUnit.getTradeRoute(); diff --git a/src/net/sf/freecol/common/networking/SetDeadMessage.java b/src/net/sf/freecol/common/networking/SetDeadMessage.java index e095793237..9595445239 100644 --- a/src/net/sf/freecol/common/networking/SetDeadMessage.java +++ b/src/net/sf/freecol/common/networking/SetDeadMessage.java @@ -54,6 +54,7 @@ public SetDeadMessage(Player player) { * @param xr The {@code FreeColXMLReader} to read from. * @exception XMLStreamException if the stream is corrupt. */ + @SuppressWarnings("PMD.UnusedFormalParameter") public SetDeadMessage(Game game, FreeColXMLReader xr) throws XMLStreamException { super(TAG, xr, PLAYER_TAG); diff --git a/src/net/sf/freecol/common/networking/SetDestinationMessage.java b/src/net/sf/freecol/common/networking/SetDestinationMessage.java index 20b22647e7..f40ccaee02 100644 --- a/src/net/sf/freecol/common/networking/SetDestinationMessage.java +++ b/src/net/sf/freecol/common/networking/SetDestinationMessage.java @@ -85,7 +85,7 @@ public ChangeSet serverHandler(FreeColServer freeColServer, Unit unit; try { unit = serverPlayer.getOurFreeColGameObject(unitId, Unit.class); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } diff --git a/src/net/sf/freecol/common/networking/SetGoodsLevelsMessage.java b/src/net/sf/freecol/common/networking/SetGoodsLevelsMessage.java index 0d109aafdd..119a729f87 100644 --- a/src/net/sf/freecol/common/networking/SetGoodsLevelsMessage.java +++ b/src/net/sf/freecol/common/networking/SetGoodsLevelsMessage.java @@ -122,7 +122,7 @@ public ChangeSet serverHandler(FreeColServer freeColServer, try { colony = serverPlayer.getOurFreeColGameObject(getStringAttribute(COLONY_TAG), Colony.class); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } ExportData exportData = getExportData(); diff --git a/src/net/sf/freecol/common/networking/SetNationMessage.java b/src/net/sf/freecol/common/networking/SetNationMessage.java index 27027f7748..8d780a1776 100644 --- a/src/net/sf/freecol/common/networking/SetNationMessage.java +++ b/src/net/sf/freecol/common/networking/SetNationMessage.java @@ -63,6 +63,7 @@ public SetNationMessage(Player player, Nation nation) { * @param xr The {@code FreeColXMLReader} to read from. * @exception XMLStreamException if the stream is corrupt. */ + @SuppressWarnings("PMD.UnusedFormalParameter") public SetNationMessage(Game game, FreeColXMLReader xr) throws XMLStreamException { super(TAG, xr, PLAYER_TAG, VALUE_TAG); diff --git a/src/net/sf/freecol/common/networking/SetNationTypeMessage.java b/src/net/sf/freecol/common/networking/SetNationTypeMessage.java index fbf8639518..633184f9be 100644 --- a/src/net/sf/freecol/common/networking/SetNationTypeMessage.java +++ b/src/net/sf/freecol/common/networking/SetNationTypeMessage.java @@ -60,6 +60,7 @@ public SetNationTypeMessage(Player player, NationType nationType) { * @param xr The {@code FreeColXMLReader} to read from. * @exception XMLStreamException if the stream is corrupt. */ + @SuppressWarnings("PMD.UnusedFormalParameter") public SetNationTypeMessage(Game game, FreeColXMLReader xr) throws XMLStreamException { super(TAG, xr, PLAYER_TAG, VALUE_TAG); diff --git a/src/net/sf/freecol/common/networking/SetStanceMessage.java b/src/net/sf/freecol/common/networking/SetStanceMessage.java index 7361115745..e2ea0678b9 100644 --- a/src/net/sf/freecol/common/networking/SetStanceMessage.java +++ b/src/net/sf/freecol/common/networking/SetStanceMessage.java @@ -61,6 +61,7 @@ public SetStanceMessage(Stance stance, Player first, Player second) { * @param xr The {@code FreeColXMLReader} to read from. * @exception XMLStreamException if the stream is corrupt. */ + @SuppressWarnings("PMD.UnusedFormalParameter") public SetStanceMessage(Game game, FreeColXMLReader xr) throws XMLStreamException { super(TAG, xr, STANCE_TAG, FIRST_TAG, SECOND_TAG); diff --git a/src/net/sf/freecol/common/networking/SpySettlementMessage.java b/src/net/sf/freecol/common/networking/SpySettlementMessage.java index 11270fcd7d..268013c402 100644 --- a/src/net/sf/freecol/common/networking/SpySettlementMessage.java +++ b/src/net/sf/freecol/common/networking/SpySettlementMessage.java @@ -159,7 +159,7 @@ public ChangeSet serverHandler(FreeColServer freeColServer, Unit unit; try { unit = getUnit(serverPlayer); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } if (!unit.hasAbility(Ability.SPY_ON_COLONY)) { diff --git a/src/net/sf/freecol/common/networking/TrainUnitInEuropeMessage.java b/src/net/sf/freecol/common/networking/TrainUnitInEuropeMessage.java index 71bee6eab5..92ca548e36 100644 --- a/src/net/sf/freecol/common/networking/TrainUnitInEuropeMessage.java +++ b/src/net/sf/freecol/common/networking/TrainUnitInEuropeMessage.java @@ -54,6 +54,7 @@ public TrainUnitInEuropeMessage(UnitType type) { * @param xr The {@code FreeColXMLReader} to read from. * @exception XMLStreamException if the stream is corrupt. */ + @SuppressWarnings("PMD.UnusedFormalParameter") public TrainUnitInEuropeMessage(Game game, FreeColXMLReader xr) throws XMLStreamException { super(TAG, xr, UNIT_TYPE_TAG); diff --git a/src/net/sf/freecol/common/networking/TrivialMessage.java b/src/net/sf/freecol/common/networking/TrivialMessage.java index 26ba4d5f34..0a2049ab69 100644 --- a/src/net/sf/freecol/common/networking/TrivialMessage.java +++ b/src/net/sf/freecol/common/networking/TrivialMessage.java @@ -88,7 +88,8 @@ protected TrivialMessage(String type) { * @param xr The {@code FreeColXMLReader} to read from. * @exception XMLStreamException if the stream is corrupt. */ - protected TrivialMessage(String tag, @SuppressWarnings("unused") Game game, + @SuppressWarnings("PMD.UnusedFormalParameter") + protected TrivialMessage(String tag, Game game, FreeColXMLReader xr) throws XMLStreamException { this(tag); @@ -130,11 +131,8 @@ protected String getStringAttribute(String key) { * {@inheritDoc} */ protected void setStringAttribute(String key, String value) { - if (key == null || value == null) { - ; // Always OK to set nothing - } else { // Nope - throw new RuntimeException(getType() + ".setStringAttribute NYI"); - } + if (key == null || value == null) return; // Always OK to set nothing + throw new RuntimeException(getType() + ".setStringAttribute NYI"); } /** @@ -162,33 +160,24 @@ protected List getChildren() { * {@inheritDoc} */ protected void setChildren(List fcos) { - if (fcos == null || fcos.isEmpty()) { - ; // Always OK to set nothing - } else { // Nope - throw new RuntimeException(getType() + ".setChildren NYI"); - } + if (fcos == null || fcos.isEmpty()) return; // Always OK to set nothing + throw new RuntimeException(getType() + ".setChildren NYI"); } /** * {@inheritDoc} */ protected void appendChild(T fco) { - if (fco == null) { - ; // Always OK to add nothing - } else { - throw new RuntimeException(getType() + ".append NYI"); - } + if (fco == null) return; // Always OK to add nothing + throw new RuntimeException(getType() + ".append NYI"); } /** * {@inheritDoc} */ protected void appendChildren(Collection fcos) { - if (fcos == null) { - ; // Always OK to add nothing - } else { - throw new RuntimeException(getType() + ".append NYI"); - } + if (fcos == null) return; // Always OK to add nothing + throw new RuntimeException(getType() + ".append NYI"); } /** diff --git a/src/net/sf/freecol/common/networking/UnloadGoodsMessage.java b/src/net/sf/freecol/common/networking/UnloadGoodsMessage.java index 17ef692649..f578044d82 100644 --- a/src/net/sf/freecol/common/networking/UnloadGoodsMessage.java +++ b/src/net/sf/freecol/common/networking/UnloadGoodsMessage.java @@ -97,7 +97,7 @@ public ChangeSet serverHandler(FreeColServer freeColServer, Unit carrier; try { carrier = serverPlayer.getOurFreeColGameObject(carrierId, Unit.class); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } if (!carrier.canCarryGoods()) { diff --git a/src/net/sf/freecol/common/networking/UpdateGameOptionsMessage.java b/src/net/sf/freecol/common/networking/UpdateGameOptionsMessage.java index 488b607e46..7c34e55b6c 100644 --- a/src/net/sf/freecol/common/networking/UpdateGameOptionsMessage.java +++ b/src/net/sf/freecol/common/networking/UpdateGameOptionsMessage.java @@ -109,9 +109,7 @@ public MessagePriority getPriority() { public void clientHandler(FreeColClient freeColClient) { final OptionGroup gameOptions = getGameOptions(); - if (freeColClient.isInGame()) { - ; // Ignored - } else { + if (!freeColClient.isInGame()) { pgc(freeColClient).updateGameOptionsHandler(gameOptions); } clientGeneric(freeColClient); diff --git a/src/net/sf/freecol/common/networking/UpdateMapGeneratorOptionsMessage.java b/src/net/sf/freecol/common/networking/UpdateMapGeneratorOptionsMessage.java index 16ffb8cc6f..ac522108e7 100644 --- a/src/net/sf/freecol/common/networking/UpdateMapGeneratorOptionsMessage.java +++ b/src/net/sf/freecol/common/networking/UpdateMapGeneratorOptionsMessage.java @@ -110,9 +110,7 @@ public MessagePriority getPriority() { public void clientHandler(FreeColClient freeColClient) { final OptionGroup mapOptions = getMapGeneratorOptions(); - if (freeColClient.isInGame()) { - ; // Ignore - } else { + if (!freeColClient.isInGame()) { pgc(freeColClient).updateMapGeneratorOptionsHandler(mapOptions); } } diff --git a/src/net/sf/freecol/common/networking/UpdateMessage.java b/src/net/sf/freecol/common/networking/UpdateMessage.java index 39f4640145..58dafe842b 100644 --- a/src/net/sf/freecol/common/networking/UpdateMessage.java +++ b/src/net/sf/freecol/common/networking/UpdateMessage.java @@ -124,12 +124,10 @@ public MessagePriority getPriority() { */ @Override public boolean merge(Message message) { - if (message instanceof UpdateMessage) { - UpdateMessage other = (UpdateMessage)message; - appendChildren(other.getChildren()); - return true; - } - return false; + if (!(message instanceof UpdateMessage)) return false; + UpdateMessage other = (UpdateMessage)message; + appendChildren(other.getChildren()); + return true; } /** diff --git a/src/net/sf/freecol/common/networking/WorkMessage.java b/src/net/sf/freecol/common/networking/WorkMessage.java index 9bd2552e49..d70502b090 100644 --- a/src/net/sf/freecol/common/networking/WorkMessage.java +++ b/src/net/sf/freecol/common/networking/WorkMessage.java @@ -93,7 +93,7 @@ public ChangeSet serverHandler(FreeColServer freeColServer, Unit unit; try { unit = serverPlayer.getOurFreeColGameObject(unitId, Unit.class); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { return serverPlayer.clientError(e.getMessage()); } diff --git a/src/net/sf/freecol/common/networking/WrapperMessage.java b/src/net/sf/freecol/common/networking/WrapperMessage.java index db234790c8..81398bed47 100644 --- a/src/net/sf/freecol/common/networking/WrapperMessage.java +++ b/src/net/sf/freecol/common/networking/WrapperMessage.java @@ -39,7 +39,7 @@ public abstract class WrapperMessage extends AttributeMessage { public static final String REPLY_ID_TAG = "networkReplyId"; /** The encapsulated message. */ - private Message message = null; + private Message message; /** @@ -132,7 +132,9 @@ public Message getMessage() { } /** - * {@inheritDoc} + * Gets the subtype of the wrapped message. + * + * @return The wrapped message type, or {@code null} if missing. */ public String getSubType() { return (this.message == null) ? null : this.message.getType(); diff --git a/src/net/sf/freecol/common/option/AbstractOption.java b/src/net/sf/freecol/common/option/AbstractOption.java index fec3ec372e..5fd9f6aaa6 100644 --- a/src/net/sf/freecol/common/option/AbstractOption.java +++ b/src/net/sf/freecol/common/option/AbstractOption.java @@ -27,6 +27,7 @@ import net.sf.freecol.common.io.FreeColXMLWriter; import net.sf.freecol.common.model.FreeColSpecObject; import net.sf.freecol.common.model.Specification; +import java.util.logging.Level; /** @@ -295,7 +296,7 @@ protected AbstractOption readOption(FreeColXMLReader xr) option = new TextOption(spec); } else { - logger.warning("Not an option type: " + tag); + if (logger.isLoggable(Level.WARNING)) logger.warning("Not an option type: " + tag); xr.nextTag(); } diff --git a/src/net/sf/freecol/common/option/GameOptions.java b/src/net/sf/freecol/common/option/GameOptions.java index 8148bedde6..925c8f67eb 100644 --- a/src/net/sf/freecol/common/option/GameOptions.java +++ b/src/net/sf/freecol/common/option/GameOptions.java @@ -541,7 +541,9 @@ public class GameOptions { // Serialization /** - * {@inheritDoc} + * Gets the XML tag name for serialization. + * + * @return The XML tag name. */ public String getXMLTagName() { return TAG; } } diff --git a/src/net/sf/freecol/common/option/IntegerOption.java b/src/net/sf/freecol/common/option/IntegerOption.java index 42f4032c75..bfb8622b82 100644 --- a/src/net/sf/freecol/common/option/IntegerOption.java +++ b/src/net/sf/freecol/common/option/IntegerOption.java @@ -216,7 +216,7 @@ protected void setValue(String valueString, String defaultValueString) { try { setValue(Integer.valueOf(str)); } catch (NumberFormatException nfe) { - logger.log(Level.WARNING, "IntegerOption fail: " + str, nfe); + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "IntegerOption fail: " + str, nfe); } } diff --git a/src/net/sf/freecol/common/option/LanguageOption.java b/src/net/sf/freecol/common/option/LanguageOption.java index 92b5c67f59..961be4f83a 100644 --- a/src/net/sf/freecol/common/option/LanguageOption.java +++ b/src/net/sf/freecol/common/option/LanguageOption.java @@ -201,8 +201,8 @@ private static void initializeLanguages() { try { languages.add(new Language(languageId, Messages.getLocale(languageId))); - } catch (Exception e) { - logger.log(Level.WARNING, "Failed to add: " + languageId, e); + } catch (IllegalArgumentException e) { + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Failed to add: " + languageId, e); } } languages.sort(Comparator.naturalOrder()); diff --git a/src/net/sf/freecol/common/option/ListOption.java b/src/net/sf/freecol/common/option/ListOption.java index ea58054bcb..9588440923 100644 --- a/src/net/sf/freecol/common/option/ListOption.java +++ b/src/net/sf/freecol/common/option/ListOption.java @@ -288,7 +288,7 @@ public void readChild(FreeColXMLReader xr) throws XMLStreamException { AbstractOption op = readChildOption(xr); if (op != null) addMember(op); } catch (XMLStreamException xse) { - logger.log(Level.WARNING, "Invalid option at: " + tag, xse); + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Invalid option at: " + tag, xse); xr.closeTag(tag); } break; diff --git a/src/net/sf/freecol/common/option/MapGeneratorOptions.java b/src/net/sf/freecol/common/option/MapGeneratorOptions.java index d10bbe4fe6..d5cd9a70da 100644 --- a/src/net/sf/freecol/common/option/MapGeneratorOptions.java +++ b/src/net/sf/freecol/common/option/MapGeneratorOptions.java @@ -19,14 +19,11 @@ package net.sf.freecol.common.option; -import net.sf.freecol.server.generator.MapGenerator; - - /** * Keeps track of the available map generator options. * More of a handy place to organize the names than an actual option type. * - * @see MapGenerator + * @see net.sf.freecol.server.generator.MapGenerator * @see net.sf.freecol.common.option.OptionGroup */ public class MapGeneratorOptions { diff --git a/src/net/sf/freecol/common/option/OptionGroup.java b/src/net/sf/freecol/common/option/OptionGroup.java index cb74322bd5..1a9e01f17e 100644 --- a/src/net/sf/freecol/common/option/OptionGroup.java +++ b/src/net/sf/freecol/common/option/OptionGroup.java @@ -350,17 +350,17 @@ protected boolean load(FreeColXMLReader xr) throws XMLStreamException { */ public boolean load(File file) { if (file == null) return false; - boolean ret = false; + boolean ret; try ( FreeColXMLReader xr = new FreeColXMLReader(file); ) { ret = load(xr); } catch (IOException|XMLStreamException xse) { - logger.log(Level.WARNING, "Load OptionGroup(" + getId() + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Load OptionGroup(" + getId() + ") from file " + file.getPath() + " crashed", xse); return false; } - logger.info("Load OptionGroup(" + getId() + ") from " + file.getPath() + if (logger.isLoggable(Level.INFO)) logger.info("Load OptionGroup(" + getId() + ") from " + file.getPath() + ((ret) ? " succeeded" : " failed")); return ret; } @@ -408,14 +408,14 @@ public > boolean hasOption(String id, public > T getOption(String id, Class returnClass) { if (id == null) { - throw new RuntimeException("Null id: " + this); + throw new IllegalArgumentException("Null id: " + this); } else if (!this.optionMap.containsKey(id)) { - throw new RuntimeException("Missing option: " + id); + throw new IllegalArgumentException("Missing option: " + id); } else { try { return returnClass.cast(optionMap.get(id)); } catch (ClassCastException cce) { - throw new RuntimeException("Not a " + returnClass.getName() + throw new IllegalArgumentException("Not a " + returnClass.getName() + ": " + id, cce); } } @@ -505,15 +505,8 @@ public boolean isNullValueOK() { */ @Override public boolean save(File file) { - boolean ret = false; - try { - ret = this.save(file, null, true); - } catch (Exception e) { - logger.log(Level.WARNING, "Save OptionGroup(" + getId() - + ") to " + file.getPath() + " crashed", e); - return false; - } - logger.info("Save OptionGroup(" + getId() + ") to " + file.getPath() + boolean ret = this.save(file, null, true); + if (logger.isLoggable(Level.INFO)) logger.info("Save OptionGroup(" + getId() + ") to " + file.getPath() + ((ret) ? " succeeded" : " failed")); return ret; } diff --git a/src/net/sf/freecol/common/option/SelectOption.java b/src/net/sf/freecol/common/option/SelectOption.java index 8d6d6cc9f3..e3cfd642ad 100644 --- a/src/net/sf/freecol/common/option/SelectOption.java +++ b/src/net/sf/freecol/common/option/SelectOption.java @@ -32,6 +32,7 @@ import net.sf.freecol.common.io.FreeColXMLReader; import net.sf.freecol.common.io.FreeColXMLWriter; import net.sf.freecol.common.model.Specification; +import java.util.logging.Level; /** @@ -48,7 +49,6 @@ */ public class SelectOption extends IntegerOption { - @SuppressWarnings("unused") private static final Logger logger = Logger.getLogger(SelectOption.class.getName()); public static final String TAG = "selectOption"; @@ -181,7 +181,7 @@ public void setValue(Integer value) { } if (fallback == null) fallback = i; } - logger.warning(TAG + ".setValue invalid value: " + if (logger.isLoggable(Level.WARNING)) logger.warning(TAG + ".setValue invalid value: " + value + ", using fallback: " + fallback); super.setValue(fallback); } diff --git a/src/net/sf/freecol/common/package-info.java b/src/net/sf/freecol/common/package-info.java index 5d4ddb2440..0983ef5457 100644 --- a/src/net/sf/freecol/common/package-info.java +++ b/src/net/sf/freecol/common/package-info.java @@ -1,5 +1,5 @@ /** - *

FreeCol Common package

+ *

FreeCol Common package

* *

Contains classes in use by both the server and the client.

* diff --git a/src/net/sf/freecol/common/resources/AudioResource.java b/src/net/sf/freecol/common/resources/AudioResource.java index 8d05cd38d6..3af72597d7 100644 --- a/src/net/sf/freecol/common/resources/AudioResource.java +++ b/src/net/sf/freecol/common/resources/AudioResource.java @@ -54,13 +54,15 @@ public AudioResource(String cachingKey, URI resourceLocator) throws IOException final File file = new File(resourceLocator); if (!file.isDirectory()) { - try (final AudioInputStream ais =SoundPlayer.getAudioInputStream(file)) { + try (final AudioInputStream stream = SoundPlayer.getAudioInputStream(file)) { + stream.getFormat(); this.files.add(file); } } else { final File[] candidateFiles = file.listFiles((dir, name) -> name.endsWith(".ogg") || name.endsWith(".wav")); for (File f : candidateFiles) { - try (final AudioInputStream ais = SoundPlayer.getAudioInputStream(f)) { + try (final AudioInputStream stream = SoundPlayer.getAudioInputStream(f)) { + stream.getFormat(); this.files.add(f); } } diff --git a/src/net/sf/freecol/common/resources/ColorResource.java b/src/net/sf/freecol/common/resources/ColorResource.java index 73f0b652b2..b25ed14191 100644 --- a/src/net/sf/freecol/common/resources/ColorResource.java +++ b/src/net/sf/freecol/common/resources/ColorResource.java @@ -108,7 +108,7 @@ private static Color createColor(String colorName) { final int col = (int) Long.decode(colorName).longValue(); return new Color(col, colorName.length() > 8); } catch (NumberFormatException e) { - logger.warning("Failed to decode hex colour string: " + if (logger.isLoggable(Level.WARNING)) logger.warning("Failed to decode hex colour string: " + colorName); } } else { diff --git a/src/net/sf/freecol/common/resources/FAFile.java b/src/net/sf/freecol/common/resources/FAFile.java index 7a67efc96d..a1b167858b 100644 --- a/src/net/sf/freecol/common/resources/FAFile.java +++ b/src/net/sf/freecol/common/resources/FAFile.java @@ -31,6 +31,7 @@ import java.util.List; import java.util.StringTokenizer; import java.util.logging.Logger; +import java.util.logging.Level; /** @@ -69,7 +70,7 @@ public String onlyValidCharacters(String text) { final char c = text.charAt(i); FALetter fl = getLetter(c); if (fl == null) { - logger.warning("Missing character in FAF: " + c); + if (logger.isLoggable(Level.WARNING)) logger.warning("Missing character in FAF: " + c); continue; } sb.append(c); @@ -98,8 +99,7 @@ public Dimension getDimension(String text) { int firstMinX = Integer.MAX_VALUE; FALetter letter = getLetter(text.charAt(0)); - for (int i=0; i lastMaxX) { lastMaxX = p.x; } @@ -138,8 +137,7 @@ public Point[] getPoints(String text) { int x = 0; for (int i=0; i imageCreator) { + Supplier imageCreator) { final long cacheKey = imageHash(key, size, grayscale, variation); final BufferedImage cached = searchCaches(cacheKey); @@ -159,10 +159,10 @@ public BufferedImage getCachedImageOrGenerate(final String key, } try { - final BufferedImage image = imageCreator.call(); + final BufferedImage image = imageCreator.get(); placeImageInLowPriorityCache(cacheKey, image); return image; - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { logger.log(Level.WARNING, "Exception while producing image", e); return null; } @@ -205,7 +205,11 @@ private void placeImageInLowPriorityCache(long hashKey, BufferedImage image) { private void debugPrintCacheSizes() { if (DEBUG_PRINT_CACHE_SIZES_TO_STDOUT) { - System.out.format("Cache: %4sMB Low priority cache: %4sMB\n", Math.round(cacheSize / (1024 * 1024)), Math.round(lowPriorityCacheSize / (1024 * 1024))); + if (logger.isLoggable(Level.FINE)) { + logger.fine(String.format("Cache: %4sMB Low priority cache: %4sMB", + Math.round(cacheSize / (1024 * 1024)), + Math.round(lowPriorityCacheSize / (1024 * 1024)))); + } } } @@ -300,7 +304,10 @@ public void run() { lowPriorityCacheSize -= ref.getSize(); lowPriorityCache.remove(ref.getKey()); } - } catch (InterruptedException e) {} + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + logger.log(Level.FINE, "Cache cleanup thread interrupted.", e); + } } } diff --git a/src/net/sf/freecol/common/resources/ImageResource.java b/src/net/sf/freecol/common/resources/ImageResource.java index f6a368f458..c3666c97c7 100644 --- a/src/net/sf/freecol/common/resources/ImageResource.java +++ b/src/net/sf/freecol/common/resources/ImageResource.java @@ -120,7 +120,7 @@ public synchronized void addAlternativeResourceLocators(List uris) { */ public BufferedImage getImage() { if (this.image == null) { - logger.finest("Preload not ready for " + getResourceLocator()); + if (logger.isLoggable(Level.FINEST)) logger.finest("Preload not ready for " + getResourceLocator()); preload(); } return this.image; @@ -324,7 +324,7 @@ private static BufferedImage loadImage(URI uri) { BufferedImage image = ImageIO.read(url); if (image == null) { - logger.log(Level.WARNING, "Failed to read image from: " + uri); + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Failed to read image from: " + uri); return null; } @@ -341,7 +341,7 @@ private static BufferedImage loadImage(URI uri) { } } catch (IOException ioe) { - logger.log(Level.WARNING, "Exception to loading image from: " + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Exception to loading image from: " + uri, ioe); } return null; diff --git a/src/net/sf/freecol/common/resources/Resource.java b/src/net/sf/freecol/common/resources/Resource.java index 12a6d1ff91..ed242eaa7d 100644 --- a/src/net/sf/freecol/common/resources/Resource.java +++ b/src/net/sf/freecol/common/resources/Resource.java @@ -35,6 +35,7 @@ public abstract class Resource { * Implement the Cleanable interface if a Resource has a use for * calls to a clean method. */ + @FunctionalInterface public interface Cleanable { /** diff --git a/src/net/sf/freecol/common/resources/ResourceFactory.java b/src/net/sf/freecol/common/resources/ResourceFactory.java index 94668e6646..716e1a8a62 100644 --- a/src/net/sf/freecol/common/resources/ResourceFactory.java +++ b/src/net/sf/freecol/common/resources/ResourceFactory.java @@ -74,7 +74,7 @@ public Resource createResource(String key, String cachingKey, URI uri) { } else if (uri.getSchemeSpecificPart().startsWith(FontResource.SCHEME)) { resource = new FontResource(cachingKey, uri); } else { - logger.log(Level.WARNING, "Unknown urn part: " + uri.getSchemeSpecificPart()); + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Unknown urn part: " + uri.getSchemeSpecificPart()); return null; } } else if (pathPart.endsWith("\"") && pathPart.lastIndexOf('"', pathPart.length()-1) >= 0) { @@ -101,7 +101,7 @@ public Resource createResource(String key, String cachingKey, URI uri) { resources.put(uri, resource); return resource; } catch (IOException ioe) { - logger.log(Level.WARNING, "Failed to create " + uri, ioe); + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Failed to create " + uri, ioe); return null; } } diff --git a/src/net/sf/freecol/common/resources/ResourceManager.java b/src/net/sf/freecol/common/resources/ResourceManager.java index b9fc566487..09e98f320f 100644 --- a/src/net/sf/freecol/common/resources/ResourceManager.java +++ b/src/net/sf/freecol/common/resources/ResourceManager.java @@ -39,6 +39,7 @@ import net.sf.freecol.common.io.FreeColDataFile; import net.sf.freecol.common.io.FreeColSavegameFile; import net.sf.freecol.common.io.sza.SimpleZippedAnimation; +import java.util.logging.Level; /** @@ -125,7 +126,7 @@ private static void waitForPreloadingToStop() { Thread.sleep(10); } } catch (InterruptedException e) { - logger.warning(e.getMessage()); + if (logger.isLoggable(Level.WARNING)) logger.warning(e.getMessage()); } } @@ -150,7 +151,7 @@ public static synchronized void startPreloading(Runnable afterPreloadHasComplete public void run() { logger.info("Preload thread started"); final int n = mergedContainer.preload(() -> !preloadDone); - logger.info("Preload done, " + n + " resources."); + if (logger.isLoggable(Level.INFO)) logger.info("Preload done, " + n + " resources."); preloadThread = null; SwingUtilities.invokeLater(() -> { afterPreloadHasCompleted.run(); @@ -183,7 +184,9 @@ public static synchronized void finishPreloading() { */ public static AudioResource getAudioResource(String key, boolean warn) { final AudioResource r = mergedContainer.getAudioResource(key); - if (warn && r == null) logger.warning("getAudioResource(" + key + ") failed"); + if (warn && r == null) { + if (logger.isLoggable(Level.WARNING)) logger.warning("getAudioResource(" + key + ") failed"); + } return r; } @@ -197,7 +200,9 @@ public static AudioResource getAudioResource(String key, boolean warn) { */ public static ColorResource getColorResource(String key, boolean warn) { final ColorResource r = mergedContainer.getColorResource(key); - if (warn && r == null) logger.warning("getColorResource(" + key + ") failed"); + if (warn && r == null) { + if (logger.isLoggable(Level.WARNING)) logger.warning("getColorResource(" + key + ") failed"); + } return r; } @@ -211,7 +216,9 @@ public static ColorResource getColorResource(String key, boolean warn) { */ public static FAFileResource getFAFileResource(String key, boolean warn) { final FAFileResource r = mergedContainer.getFAFileResource(key); - if (warn && r == null) logger.warning("getFAFileResource(" + key + ") failed"); + if (warn && r == null) { + if (logger.isLoggable(Level.WARNING)) logger.warning("getFAFileResource(" + key + ") failed"); + } return r; } @@ -225,7 +232,9 @@ public static FAFileResource getFAFileResource(String key, boolean warn) { */ public static FontResource getFontResource(String key, boolean warn) { final FontResource r = mergedContainer.getFontResource(key); - if (warn && r == null) logger.warning("getFontResource(" + key + ") failed"); + if (warn && r == null) { + if (logger.isLoggable(Level.WARNING)) logger.warning("getFontResource(" + key + ") failed"); + } return r; } @@ -240,7 +249,9 @@ public static FontResource getFontResource(String key, boolean warn) { public static ImageResource getImageResource(String key, boolean warn) { // Public for ImageCache final ImageResource r = mergedContainer.getImageResource(key); - if (warn && r == null) logger.warning("getImageResource(" + key + ") failed"); + if (warn && r == null) { + if (logger.isLoggable(Level.WARNING)) logger.warning("getImageResource(" + key + ") failed"); + } return r; } @@ -254,7 +265,9 @@ public static ImageResource getImageResource(String key, boolean warn) { */ public static StringResource getStringResource(String key, boolean warn) { final StringResource r = mergedContainer.getStringResource(key); - if (warn && r == null) logger.warning("getStringResource(" + key + ") failed"); + if (warn && r == null) { + if (logger.isLoggable(Level.WARNING)) logger.warning("getStringResource(" + key + ") failed"); + } return r; } @@ -268,7 +281,9 @@ public static StringResource getStringResource(String key, boolean warn) { */ public static SZAResource getSZAResource(String key, boolean warn) { final SZAResource r = mergedContainer.getSZAResource(key); - if (warn && r == null) logger.warning("getSZAResource(" + key + ") failed"); + if (warn && r == null) { + if (logger.isLoggable(Level.WARNING)) logger.warning("getSZAResource(" + key + ") failed"); + } return r; } @@ -282,7 +297,9 @@ public static SZAResource getSZAResource(String key, boolean warn) { */ public static VideoResource getVideoResource(String key, boolean warn) { final VideoResource r = mergedContainer.getVideoResource(key); - if (warn && r == null) logger.warning("getVideoResource(" + key + ") failed"); + if (warn && r == null) { + if (logger.isLoggable(Level.WARNING)) logger.warning("getVideoResource(" + key + ") failed"); + } return r; } diff --git a/src/net/sf/freecol/common/resources/ResourceMapping.java b/src/net/sf/freecol/common/resources/ResourceMapping.java index 7a49f63245..b623aee27d 100644 --- a/src/net/sf/freecol/common/resources/ResourceMapping.java +++ b/src/net/sf/freecol/common/resources/ResourceMapping.java @@ -23,6 +23,7 @@ import java.util.Map; import java.util.Set; import java.util.logging.Logger; +import java.util.logging.Level; /** @@ -298,6 +299,7 @@ public void clearCaches() { imageResources.values().stream().forEach(r -> r.clean()); } + @FunctionalInterface public interface PreloadController { boolean shouldContinue(); } @@ -323,7 +325,7 @@ public ResourceType(Class clazz, String requiredKeyPrefix, Map res boolean put(String key, Object resource) { if (requiredKeyPrefix != null && !key.startsWith(requiredKeyPrefix)) { - logger.warning("Rejecting malformed resource key: \"" + if (logger.isLoggable(Level.WARNING)) logger.warning("Rejecting malformed resource key: \"" + key + "\". The key should have started with: \"" + requiredKeyPrefix + "\"."); return false; } diff --git a/src/net/sf/freecol/common/resources/SZAResource.java b/src/net/sf/freecol/common/resources/SZAResource.java index a9a0286e09..3e1725d07b 100644 --- a/src/net/sf/freecol/common/resources/SZAResource.java +++ b/src/net/sf/freecol/common/resources/SZAResource.java @@ -67,7 +67,7 @@ public void preload() { = new SimpleZippedAnimation(getResourceLocator().toURL()); this.cache.put(DEFAULT_SCALE, sza); } catch (IOException e) { - logger.log(Level.WARNING, + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Could not load SimpleZippedAnimation: " + getResourceLocator(), e); } diff --git a/src/net/sf/freecol/common/sound/OggVorbisDecoderFactory.java b/src/net/sf/freecol/common/sound/OggVorbisDecoderFactory.java index 2e27696d23..20027e5255 100644 --- a/src/net/sf/freecol/common/sound/OggVorbisDecoderFactory.java +++ b/src/net/sf/freecol/common/sound/OggVorbisDecoderFactory.java @@ -81,7 +81,7 @@ private static class OggStream extends InputStream { private float[][][] pcmData; // The stream containing the data. - private InputStream inputStream = null; + private InputStream inputStream; public OggStream(InputStream inputStream) throws IOException { @@ -241,7 +241,8 @@ private String getHeader() { packet = 1; break; case 0: - if ((input = getInput()) != null) return input; + input = getInput(); + if (input != null) return input; break; default: return "Error reading first page"; @@ -256,7 +257,8 @@ private String getHeader() { packet++; break; case 0: - if ((input = getPage()) != null) return input; + input = getPage(); + if (input != null) return input; break; default: return "Error in header packet " + packet; @@ -273,7 +275,7 @@ private String getHeader() { * @return An error message if input is not available, null on success. */ private String getInput() { - int count = -1; + int count; try { int idx = oggSyncState.buffer(BUFSIZ); count = inputStream.read(oggSyncState.data, idx, BUFSIZ); @@ -294,7 +296,8 @@ private String getPage() { for (;;) { switch (oggSyncState.pageout(oggPage)) { case 0: - if ((input = getInput()) != null) return input; + input = getInput(); + if (input != null) return input; break; case 1: oggStreamState.pagein(oggPage); @@ -330,7 +333,8 @@ public int getBody(InputStream is) { } break; case 0: - if ((err = getPage()) != null) { + err = getPage(); + if (err != null) { return (EOS.equals(err)) ? 0 : -1; } break; @@ -375,7 +379,7 @@ private int decodePacket(int samples) { private static class OggVorbisAudioInputStream extends AudioInputStream { // Core JOgg and JOrbis magic. - private OggStream os = null; + private OggStream os; /** diff --git a/src/net/sf/freecol/common/sound/SoundPlayer.java b/src/net/sf/freecol/common/sound/SoundPlayer.java index 7316109134..48f7864009 100644 --- a/src/net/sf/freecol/common/sound/SoundPlayer.java +++ b/src/net/sf/freecol/common/sound/SoundPlayer.java @@ -130,10 +130,10 @@ private File remove() { private boolean playSound(File sound) throws IOException { setVolume(volumeOption.getValue()); - boolean ret = false; + boolean ret; PropertyChangeListener volumeListener = null; - try (AudioInputStream in = getAudioInputStream(sound)) { - final SourceDataLine line = openLine(in.getFormat(), getMixer(), data.length); + try (AudioInputStream in = getAudioInputStream(sound); + SourceDataLine line = openLine(in.getFormat(), getMixer(), data.length)) { if (line == null) { return false; } @@ -156,10 +156,9 @@ private boolean playSound(File sound) throws IOException { this.playDone = true; line.drain(); line.stop(); - line.close(); } } catch (IOException ioe) { - logger.log(Level.WARNING, "Can not open " + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Can not open " + sound + " as audio stream", ioe); return false; } finally { @@ -262,10 +261,10 @@ public Mixer getMixer () { private void setMixer(MixerWrapper mw) { try { this.mixer = AudioSystem.getMixer(mw.getMixerInfo()); - logger.info("Mixer " + mw + " selected"); - } catch (Exception e) { + if (logger.isLoggable(Level.INFO)) logger.info("Mixer " + mw + " selected"); + } catch (IllegalArgumentException | SecurityException e) { this.mixer = null; - logger.log(Level.WARNING, "Bad mixer: " + mw + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Bad mixer: " + mw + ", sound suspended", e); } } @@ -303,7 +302,7 @@ public boolean playOnce(File file) { /** * Defines the default playlist. * - * @param file The {@code File}s to be played when + * @param files The {@code File}s to be played when * nothing else is being played. */ public void setDefaultPlaylist(File... files) { @@ -401,11 +400,11 @@ private static void changeVolume(SourceDataLine line, int vol) { : min + 0.5f * (max - min) * (float)Math.log10(vol); try { control.setValue(gain); - logger.finest("Using volume " + vol + "%, " + if (logger.isLoggable(Level.FINEST)) logger.finest("Using volume " + vol + "%, " + control.getUnits() + "=" + gain + " control=" + type); } catch (IllegalArgumentException ie) { - logger.log(Level.WARNING, "Could not set volume " + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Could not set volume " + " (control=" + type + " in [" + min + "," + max + "])" + " to " + gain + control.getUnits(), ie); } @@ -428,10 +427,10 @@ private static SourceDataLine openLine(AudioFormat audioFormat, return null; } if (!mixer.isLineSupported(info)) { - logger.log(Level.WARNING, "Mixer does not support " + info); + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Mixer does not support " + info); return null; } - SourceDataLine line = null; + SourceDataLine line; try { line = (SourceDataLine)mixer.getLine(info); line.open(audioFormat, len); diff --git a/src/net/sf/freecol/common/sound/package-info.java b/src/net/sf/freecol/common/sound/package-info.java index f1bd7c20c9..14b2561973 100644 --- a/src/net/sf/freecol/common/sound/package-info.java +++ b/src/net/sf/freecol/common/sound/package-info.java @@ -1,5 +1,5 @@ /** - *

FreeCol Sound and Music package

+ *

FreeCol Sound and Music package

* *

This package contains the classes for handling sound effects and music in FreeCol. * {@link net.sf.freecol.client.FreeColClient} initializes {@link net.sf.freecol.client.control.SoundController} which diff --git a/src/net/sf/freecol/common/util/CachingFunction.java b/src/net/sf/freecol/common/util/CachingFunction.java index eb1ee8d149..039014efc8 100644 --- a/src/net/sf/freecol/common/util/CachingFunction.java +++ b/src/net/sf/freecol/common/util/CachingFunction.java @@ -53,6 +53,7 @@ public CachingFunction(Function wrapped) { */ @SuppressFBWarnings(value="MUI_CONTAINSKEY_BEFORE_GET", justification="Deliberate to all null values") + @Override public R apply(T t) { R result; // Normally we would just use get(), but this is a general routine diff --git a/src/net/sf/freecol/common/util/CollectionUtils.java b/src/net/sf/freecol/common/util/CollectionUtils.java index 12fc45d296..f7914057c9 100644 --- a/src/net/sf/freecol/common/util/CollectionUtils.java +++ b/src/net/sf/freecol/common/util/CollectionUtils.java @@ -44,6 +44,8 @@ import java.util.stream.Collector; import java.util.stream.Collectors; import java.util.stream.Stream; +import java.util.logging.Level; +import java.util.logging.Logger; import java.util.stream.StreamSupport; @@ -52,6 +54,8 @@ */ public class CollectionUtils { + private static final Logger logger = Logger.getLogger(CollectionUtils.class.getName()); + private static final int MAX_DEFAULT = Integer.MIN_VALUE; private static final int MIN_DEFAULT = Integer.MAX_VALUE; private static final int SUM_DEFAULT = 0; @@ -120,7 +124,7 @@ public static List makeUnmodifiableList(T... members) { * @param values The array of values. * @return An unmodifiable map containing the specified members. */ - public static Map makeUnmodifiableMap(K[] keys, V[] values) { + public static Map makeUnmodifiableMap(K[] keys, V... values) { if (keys.length != values.length) { throw new RuntimeException("Length mismatch: " + keys.length + " != " + values.length); @@ -298,7 +302,7 @@ public static void rotate(final List list, int n) { } } else { for (; n < 0; n++) { - T t = list.remove(n-1); + T t = list.remove(list.size() - 1); list.add(0, t); } } @@ -313,10 +317,14 @@ public static void rotate(final List list, int n) { public static void reverse(final List list) { final int len = list.size(); if (len <= 0) return; - for (int i = 0, j = len-1; i < j; i++, j--) { + int i = 0; + int j = len - 1; + while (i < j) { T t = list.get(i); list.set(i, list.get(j)); list.set(j, t); + i++; + j--; } } @@ -476,7 +484,7 @@ public static Predicate alwaysTrue() { * @param array The array to test. * @return True if the array is non-empty. */ - public static boolean any(T[] array) { + public static boolean any(T... array) { return array != null && array.length > 0; } @@ -609,8 +617,8 @@ public static Comparator cachingDoubleComparator(Function f) { public static Stream concat(Stream s0, Stream... streams) { Stream[] sts = streams; Stream ret = (s0 == null) ? Stream.empty() : s0; - for (int i = 0; i < sts.length; i++) { - if (sts[i] != null) ret = Stream.concat(ret, sts[i]); + for (Stream stream : sts) { + if (stream != null) ret = Stream.concat(ret, stream); } return ret; } @@ -622,7 +630,7 @@ public static Stream concat(Stream s0, Stream... streams) { * @param array The array to check. * @return The number of items that matched. */ - public static int count(T[] array) { + public static int count(T... array) { return (array == null) ? 0 : array.length; } @@ -707,7 +715,7 @@ private static int count_internal(Stream stream, * @param header Optional informational string to print first. * @param array The array to dump. */ - public static void dump(String header, T[] array) { + public static void dump(String header, T... array) { dump_internal(header, Arrays.stream(array)); } @@ -738,13 +746,12 @@ public static void dump(String header, Stream stream) { * @param stream The {@code Stream} to print. */ private static void dump_internal(String header, Stream stream) { - if (header != null) System.err.print(header); - System.err.print("[ "); - forEach(stream, (v) -> { - System.err.print(v); - System.err.print(' '); - }); - System.err.println(']'); + StringBuilder sb = new StringBuilder(128); + if (header != null) sb.append(header); + sb.append("[ "); + forEach(stream, (v) -> sb.append(v).append(' ')); + sb.append(']'); + if (logger.isLoggable(Level.FINE)) logger.fine(sb.toString()); } /** @@ -754,15 +761,17 @@ private static void dump_internal(String header, Stream stream) { * @param map The {@code Map} to print. */ public static void dump(String header, Map map) { - if (header != null) System.err.print(header); - System.err.print("[ "); + StringBuilder sb = new StringBuilder(128); + if (header != null) sb.append(header); + sb.append("[ "); forEachMapEntry(map, (e) -> { - System.err.print(e.getKey()); - System.err.print(','); - System.err.print(e.getValue()); - System.err.print(' '); + sb.append(e.getKey()); + sb.append(','); + sb.append(e.getValue()); + sb.append(' '); }); - System.err.println(']'); + sb.append(']'); + if (logger.isLoggable(Level.FINE)) logger.fine(sb.toString()); } /** @@ -892,7 +901,7 @@ private static T find_internal(Stream stream, * @param array The {@code Collection} to search. * @return The first item, or null on failure. */ - public static T first(T[] array) { + public static T first(T... array) { return (array == null || array.length == 0) ? null : first_internal(Arrays.stream(array), null); } @@ -1235,6 +1244,7 @@ public static Predicate isNull(Function mapper) { */ public static Iterable iterable(final Stream stream) { return new Iterable() { + @Override public Iterator iterator() { return stream.iterator(); } }; } @@ -1764,7 +1774,7 @@ private static T minimize_internal(Stream stream, * @param array The array to test. * @return True if an array is null or empty. */ - public static boolean none(T[] array) { + public static boolean none(T... array) { return array == null || array.length == 0; } @@ -1992,7 +2002,7 @@ public static boolean removeInPlace(Map map, * @param array The array to convert. * @return A list of the stream contents. */ - public static > List sort(T[] array) { + public static > List sort(T... array) { final Comparator comparator = Comparator.naturalOrder(); return sort_internal(Arrays.stream(array), comparator); } @@ -2293,7 +2303,7 @@ public static Collector,?,List> toAppendedList() { * @param array The array to convert. * @return A map of the stream contents. */ - public static List toList(T[] array) { + public static List toList(T... array) { return toList_internal(Arrays.stream(array)); } diff --git a/src/net/sf/freecol/common/util/ImageUtils.java b/src/net/sf/freecol/common/util/ImageUtils.java index 9c31e7562d..225a4389c0 100644 --- a/src/net/sf/freecol/common/util/ImageUtils.java +++ b/src/net/sf/freecol/common/util/ImageUtils.java @@ -319,7 +319,7 @@ public static Dimension wildcardDimension(Dimension d, Dimension nominal) { public static BufferedImage fadeImage(Image img, float fade, float target) { int w = img.getWidth(null); int h = img.getHeight(null); - final BufferedImage bi = createBufferedImage(w, h);; + final BufferedImage bi = createBufferedImage(w, h); final Graphics2D g = bi.createGraphics(); g.drawImage(img, 0, 0, null); diff --git a/src/net/sf/freecol/common/util/Introspector.java b/src/net/sf/freecol/common/util/Introspector.java index aa75debcb6..f0be0ad54f 100644 --- a/src/net/sf/freecol/common/util/Introspector.java +++ b/src/net/sf/freecol/common/util/Introspector.java @@ -122,15 +122,7 @@ private static String fromSnakeCase(String nameInSnakeCase) { */ private Class getMethodReturnType(Method method) throws IntrospectorException { - Class ret; - - try { - ret = method.getReturnType(); - } catch (Exception e) { - throw new IntrospectorException(theClass.getName() - + "." + method.getName() + " return type.", e); - } - return ret; + return method.getReturnType(); } /** @@ -213,7 +205,7 @@ public String getter(Object obj) throws IntrospectorException { e); } } else { - Object result = null; + Object result; try { result = getMethod.invoke(obj); } catch (IllegalAccessException | IllegalArgumentException @@ -271,7 +263,7 @@ public void setter(Object obj, String value) throws IntrospectorException { } } else { Method convertMethod = getFromStringConverter(fieldType); - Object result = null; + Object result; if (fieldType.isEnum()) { try { @@ -323,7 +315,7 @@ public static Class getClassByName(String name) { * @param types The types of the constructor arguments. * @return The constructor found, or null on error. */ - public static Constructor getConstructor(Class cl, Class[] types) { + public static Constructor getConstructor(Class cl, Class... types) { Constructor constructor; try { constructor = cl.getDeclaredConstructor(types); @@ -342,7 +334,7 @@ public static Constructor getConstructor(Class cl, Class[] types) { * @return The instance created, or null on error. * @exception IntrospectorException if there is a FreeCol failure. */ - public static T construct(Constructor constructor, Object[] params) + public static T construct(Constructor constructor, Object... params) throws IntrospectorException { T instance; try { @@ -365,7 +357,7 @@ public static T construct(Constructor constructor, Object[] params) * @return The new object instance. * @exception IntrospectorException wraps all exceptional conditions. */ - public static Object instantiate(String tag, Class[] types, Object[] params) + public static Object instantiate(String tag, Class[] types, Object... params) throws IntrospectorException { Class messageClass; try { @@ -387,7 +379,7 @@ public static Object instantiate(String tag, Class[] types, Object[] params) * @return The new instance. * @exception IntrospectorException wraps all exceptional conditions. */ - public static T instantiate(Class messageClass, Class[] types, Object[] params) + public static T instantiate(Class messageClass, Class[] types, Object... params) throws IntrospectorException { final String tag = messageClass.getName(); Constructor constructor; diff --git a/src/net/sf/freecol/common/util/RandomUtils.java b/src/net/sf/freecol/common/util/RandomUtils.java index c974ca6a34..156c89fd61 100644 --- a/src/net/sf/freecol/common/util/RandomUtils.java +++ b/src/net/sf/freecol/common/util/RandomUtils.java @@ -86,7 +86,7 @@ public int nextInt(int tighterRange) { public static int randomInt(Logger logger, String logMe, Random random, int range) { int ret = random.nextInt(range); - if (logger != null) { + if (logger != null && logger.isLoggable(Level.FINEST)) { logger.finest(logMe + " random(" + range + ") = " + ret); } return ret; @@ -99,11 +99,11 @@ public static int randomInt(Logger logger, String logMe, Random random, * @param logMe A string to log with the result. * @param arr The array of ints to log. */ - public static void logArray(Logger logger, String logMe, int[] arr) { + public static void logArray(Logger logger, String logMe, int... arr) { if (logger != null && logger.isLoggable(Level.FINEST)) { StringBuilder sb = new StringBuilder(64); sb.append(logMe).append(" random").append(" = ["); - for (int i = 0; i < arr.length; i++) sb.append(' ').append(arr[i]); + for (int value : arr) sb.append(' ').append(value); sb.append(" ]"); logger.finest(sb.toString()); } diff --git a/src/net/sf/freecol/common/util/StringUtils.java b/src/net/sf/freecol/common/util/StringUtils.java index 9b20f2bd63..86023b1eef 100644 --- a/src/net/sf/freecol/common/util/StringUtils.java +++ b/src/net/sf/freecol/common/util/StringUtils.java @@ -120,7 +120,8 @@ public static String getEnumKey(Enum value) { StringBuilder sb = new StringBuilder(len); int idx, from = 0; for (;;) { - if ((idx = base.indexOf('_', from)) < 0) { + idx = base.indexOf('_', from); + if (idx < 0) { sb.append(base.substring(from)); break; } diff --git a/src/net/sf/freecol/common/util/Utils.java b/src/net/sf/freecol/common/util/Utils.java index 87cecfc214..8ce1e41fae 100644 --- a/src/net/sf/freecol/common/util/Utils.java +++ b/src/net/sf/freecol/common/util/Utils.java @@ -154,7 +154,7 @@ public static Reader getFileUTF8Reader(File file) { InputStream fis = Files.newInputStream(file.toPath()); return new InputStreamReader(fis, StandardCharsets.UTF_8); } catch (IOException ioe) { - logger.log(Level.WARNING, "No input stream for " + file.getPath(), + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "No input stream for " + file.getPath(), ioe); } return null; @@ -174,7 +174,7 @@ public static String getUTF8Contents(File file) { try { reader.read(cb); } catch (IOException ioe) { - logger.log(Level.WARNING, "Read failed for " + file.getPath(), + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Read failed for " + file.getPath(), ioe); } cb.flip(); @@ -212,7 +212,7 @@ private static Writer getF8W(File file, boolean append) { : Files.newOutputStream(file.toPath()); return getUTF8Writer(fos); } catch (IOException ioe) { - logger.log(Level.WARNING, "No output stream for " + file.getName(), + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "No output stream for " + file.getName(), ioe); } return null; @@ -277,10 +277,10 @@ public static Transformer makeTransformer(boolean declaration, public static void deleteFile(File file) { try { if (!file.delete()) { - logger.warning("Failed to delete: " + file.getPath()); + if (logger.isLoggable(Level.WARNING)) logger.warning("Failed to delete: " + file.getPath()); } } catch (SecurityException ex) { - logger.log(Level.WARNING, "Exception deleting: " + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Exception deleting: " + file.getPath(), ex); } } @@ -380,13 +380,17 @@ public static boolean isHeadless() { public static GraphicsDevice getGoodGraphicsDevice() { try { return MouseInfo.getPointerInfo().getDevice(); - } catch (HeadlessException he) {} + } catch (HeadlessException he) { + logger.log(Level.FINE, "Headless environment, no pointer device.", he); + } try { final GraphicsEnvironment lge = GraphicsEnvironment.getLocalGraphicsEnvironment(); return lge.getDefaultScreenDevice(); - } catch (HeadlessException he) {} + } catch (HeadlessException he) { + logger.log(Level.FINE, "Headless environment, no screen device.", he); + } return null; } diff --git a/src/net/sf/freecol/metaserver/MetaRegister.java b/src/net/sf/freecol/metaserver/MetaRegister.java index 3c7448fc90..45a2fe6bd2 100644 --- a/src/net/sf/freecol/metaserver/MetaRegister.java +++ b/src/net/sf/freecol/metaserver/MetaRegister.java @@ -102,11 +102,7 @@ private void startCleanupTimer() { t.scheduleAtFixedRate(new TimerTask() { @Override public void run() { - try { - removeDeadServers(); - } catch (Exception ex) { - logger.log(Level.WARNING, "Could not remove servers.", ex); - } + removeDeadServers(); } }, REMOVE_DEAD_SERVERS_INTERVAL, REMOVE_DEAD_SERVERS_INTERVAL); } @@ -129,12 +125,12 @@ public synchronized boolean addServer(ServerInfo newSi) { final String identity = newSi.getName() + " (" + newSi.getAddress() + ":" + newSi.getPort() + ")"; if (!canConnectToServer(newSi)) { - logger.log(Level.INFO, "Cannot connect to server: " + identity); + if (logger.isLoggable(Level.INFO)) logger.log(Level.INFO, "Cannot connect to server: " + identity); return false; } items.add(newSi); - logger.info("Server added:" + identity); + if (logger.isLoggable(Level.INFO)) logger.info("Server added:" + identity); return true; } @@ -167,7 +163,7 @@ public synchronized void removeDeadServers() { long time = now() - REMOVE_OLDER_THAN; for (int i=0; i= 0) { items.remove(index); - logger.info("Removing server:" + address + ":" + port); + if (logger.isLoggable(Level.INFO)) logger.info("Removing server:" + address + ":" + port); } else { - logger.warning("Trying to remove non-existing server:" + if (logger.isLoggable(Level.WARNING)) logger.warning("Trying to remove non-existing server:" + address + ":" + port); } } diff --git a/src/net/sf/freecol/metaserver/MetaServer.java b/src/net/sf/freecol/metaserver/MetaServer.java index b330145b91..d25a73015c 100644 --- a/src/net/sf/freecol/metaserver/MetaServer.java +++ b/src/net/sf/freecol/metaserver/MetaServer.java @@ -126,10 +126,10 @@ public void run() { // new client connects to the server a new {@link Connection} // is made, with {@link MetaServerHandler} as the input handler. while (this.running) { - Socket clientSocket = null; + Socket clientSocket; try { clientSocket = serverSocket.accept(); - logger.info("Client connection from: " + if (logger.isLoggable(Level.INFO)) logger.info("Client connection from: " + clientSocket.getInetAddress().toString()); @SuppressWarnings("resource") final Connection connection = new Connection(clientSocket, FreeCol.METASERVER_THREAD).setMessageHandler(getMetaServerHandler()); @@ -153,8 +153,10 @@ public static void main(String[] args) { try { port = Integer.parseInt(args[0]); } catch (ArrayIndexOutOfBoundsException|NumberFormatException e) { - System.out.println("Usage: " + MetaServer.class.getName() - + " PORT_NUMBER"); + if (logger.isLoggable(Level.INFO)) { + logger.info("Usage: " + MetaServer.class.getName() + + " PORT_NUMBER"); + } System.exit(1); } diff --git a/src/net/sf/freecol/metaserver/MetaServerHandler.java b/src/net/sf/freecol/metaserver/MetaServerHandler.java index 95aeaf42f5..8427bed245 100644 --- a/src/net/sf/freecol/metaserver/MetaServerHandler.java +++ b/src/net/sf/freecol/metaserver/MetaServerHandler.java @@ -34,6 +34,7 @@ import net.sf.freecol.common.networking.RemoveServerMessage; import net.sf.freecol.common.networking.ServerListMessage; import net.sf.freecol.common.networking.UpdateServerMessage; +import java.util.logging.Level; /** @@ -100,7 +101,7 @@ public Message handle(Connection connection, Message message) update(usm); break; default: - logger.warning("Unknown request: " + tag); + if (logger.isLoggable(Level.WARNING)) logger.warning("Unknown request: " + tag); break; } return reply; diff --git a/src/net/sf/freecol/metaserver/package-info.java b/src/net/sf/freecol/metaserver/package-info.java index ce5d25d052..da4c85a40e 100644 --- a/src/net/sf/freecol/metaserver/package-info.java +++ b/src/net/sf/freecol/metaserver/package-info.java @@ -1,5 +1,5 @@ /** - *

FreeCol Meta server

+ *

FreeCol Meta server

* *

This package contains an implementation of a meta server.

* diff --git a/src/net/sf/freecol/package-info.java b/src/net/sf/freecol/package-info.java index 06ab4e80f3..0862c28de4 100644 --- a/src/net/sf/freecol/package-info.java +++ b/src/net/sf/freecol/package-info.java @@ -1,5 +1,5 @@ /** - *

FreeCol

+ *

FreeCol

* *

The base FreeCol package containing all subclasses.

* diff --git a/src/net/sf/freecol/server/FreeColServer.java b/src/net/sf/freecol/server/FreeColServer.java index d5b1447c90..6cb7cf6350 100644 --- a/src/net/sf/freecol/server/FreeColServer.java +++ b/src/net/sf/freecol/server/FreeColServer.java @@ -292,7 +292,7 @@ private Server createServer(InetAddress address, int firstPort) throws IOExcepti for (int i = tryMax; i > 0; i--) { try { Server ret = new Server(this, host, port); - logger.finest("Server started: " + ret.getHost() + if (logger.isLoggable(Level.FINEST)) logger.finest("Server started: " + ret.getHost() + ", " + ret.getPort()); return ret; } catch (IOException ioe) { @@ -667,7 +667,7 @@ public void addNewUserConnection(Socket socket) if (this.serverState == ServerState.IN_GAME) { c.send(new VacantPlayersMessage().setVacantPlayers(getGame())); } - logger.info("Client connected from " + name); + if (logger.isLoggable(Level.INFO)) logger.info("Client connected from " + name); } /** @@ -735,10 +735,11 @@ private void addAIConnection(Player aiPlayer) { public ServerGame waitForGame() { final int timeStep = 1000; int timeOut = 20000; - ServerGame serverGame = null; + ServerGame serverGame; while ((serverGame = getGame()) == null) { delay(timeStep, "waitForGame delay interrupt"); - if ((timeOut -= timeStep) <= 0) break; + timeOut -= timeStep; + if (timeOut <= 0) break; } return serverGame; } @@ -761,7 +762,7 @@ public ServerGame waitForGame() { * @exception FreeColException if there is a problem creating the game. */ public void startGame() throws FreeColException { - logger.info("Server starting game: " + this.serverState); + if (logger.isLoggable(Level.INFO)) logger.info("Server starting game: " + this.serverState); switch (this.serverState) { case PRE_GAME: // Send the updated game to the clients. @@ -777,7 +778,7 @@ public void startGame() throws FreeColException { case LOAD_GAME: // Do nothing, game has been sent. break; default: - logger.warning("Invalid startGame when server state = " + if (logger.isLoggable(Level.WARNING)) logger.warning("Invalid startGame when server state = " + this.serverState); return; } @@ -983,7 +984,7 @@ private static ServerGame readGame(File file, Specification spec, ServerGame serverGame = FreeColServer.readGame(new FreeColSavegameFile(file), spec, freeColServer); - logger.info("Read file " + file.getPath()); + if (logger.isLoggable(Level.INFO)) logger.info("Read file " + file.getPath()); // If importing as a result of "Start Game" in the map editor, // consume the file. @@ -1012,7 +1013,7 @@ public static ServerGame readGame(final FreeColSavegameFile fis, FreeColServer freeColServer) throws FreeColException, IOException, XMLStreamException { final int savegameVersion = fis.getSavegameVersion(); - logger.info("Found savegame version " + savegameVersion); + if (logger.isLoggable(Level.INFO)) logger.info("Found savegame version " + savegameVersion); if (savegameVersion < MINIMUM_SAVEGAME_VERSION) { throw new FreeColException("server.incompatibleVersions: " + savegameVersion + " < " + MINIMUM_SAVEGAME_VERSION); @@ -1110,10 +1111,10 @@ private ServerGame loadGame(final FreeColSavegameFile fis, logger.info("Game integrity test succeeded."); break; case INTEGRITY_FIXED: - logger.info("Game integrity test failed, but fixed." + lb); + if (logger.isLoggable(Level.INFO)) logger.info("Game integrity test failed, but fixed." + lb); break; default: - logger.warning("Game integrity test failed." + lb); + if (logger.isLoggable(Level.WARNING)) logger.warning("Game integrity test failed." + lb); break; } @@ -1139,13 +1140,13 @@ private ServerGame loadGame(final FreeColSavegameFile fis, logger.info("AI integrity test succeeded."); break; case INTEGRITY_FIXED: - logger.info("AI integrity test failed, but fixed." + lb); + if (logger.isLoggable(Level.INFO)) logger.info("AI integrity test failed, but fixed." + lb); break; default: aiMain = new AIMain(this); aiMain.findNewObjects(true); setAIMain(aiMain); - logger.warning("AI integrity test failed, replaced AIMain." + lb); + if (logger.isLoggable(Level.WARNING)) logger.warning("AI integrity test failed, replaced AIMain." + lb); break; } serverGame.setFreeColGameObjectListener(aiMain); @@ -1264,7 +1265,7 @@ public Map generateMap(boolean generateEuropeanPlayerUnits) { importMap = FreeColServer.readMap(importFile, serverGame.getSpecification()); } catch (FreeColException|IOException|XMLStreamException ex) { - logger.log(Level.WARNING, "Failed to import map: " + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Failed to import map: " + importFile.getName(), ex); } } diff --git a/src/net/sf/freecol/server/ai/AIColony.java b/src/net/sf/freecol/server/ai/AIColony.java index 294966a8e0..1d354f9505 100644 --- a/src/net/sf/freecol/server/ai/AIColony.java +++ b/src/net/sf/freecol/server/ai/AIColony.java @@ -249,7 +249,7 @@ public Set rearrangeColony(LogBuilder lb) { if (colony.getCurrentlyBuilding() == null && colonyPlan != null && colonyPlan.getBestBuildableType() != null) { - logger.warning(colony.getName() + " could be building but" + if (logger.isLoggable(Level.WARNING)) logger.warning(colony.getName() + " could be building but" + " is asleep until turn: " + rearrangeTurn.getNumber() + "( > " + turn + ")"); } else { @@ -342,7 +342,7 @@ public Set rearrangeColony(LogBuilder lb) { sb.append("Autodestruct at ").append(colony.getName()) .append(" in ").append(turn).append(':'); for (UnitWas uw : was) sb.append('\n').append(uw); - logger.warning(sb.toString()); + if (logger.isLoggable(Level.WARNING)) logger.warning(sb.toString()); if (!avertAutoDestruction()) return result; } diff --git a/src/net/sf/freecol/server/ai/AIGoods.java b/src/net/sf/freecol/server/ai/AIGoods.java index e33dcce8b9..ea6788bc5f 100644 --- a/src/net/sf/freecol/server/ai/AIGoods.java +++ b/src/net/sf/freecol/server/ai/AIGoods.java @@ -41,6 +41,7 @@ import net.sf.freecol.common.util.LogBuilder; import net.sf.freecol.common.util.Utils; import net.sf.freecol.server.ai.mission.Mission; +import java.util.logging.Level; /** @@ -121,7 +122,7 @@ public void setInitialized() { * * @return The {@code Goods}. */ - public final Goods getGoods() { + public Goods getGoods() { return this.goods; } @@ -130,7 +131,7 @@ public final Goods getGoods() { * * @param goods The new {@code Goods}. */ - public final void setGoods(Goods goods) { + public void setGoods(Goods goods) { this.goods = goods; } @@ -139,7 +140,7 @@ public final void setGoods(Goods goods) { * * @return The {@code GoodsType}. */ - public final GoodsType getGoodsType() { + public GoodsType getGoodsType() { return goods.getType(); } @@ -148,7 +149,7 @@ public final GoodsType getGoodsType() { * * @return The amount of goods. */ - public final int getGoodsAmount() { + public int getGoodsAmount() { return goods.getAmount(); } @@ -157,7 +158,7 @@ public final int getGoodsAmount() { * * @param amount The new amount of goods. */ - public final void setGoodsAmount(int amount) { + public void setGoodsAmount(int amount) { goods.setAmount(amount); } @@ -184,11 +185,11 @@ private boolean leaveTransport(int amount) { if (oldAmount - newAmount != amount) { // FIXME: sort this out. // For now, do not tolerate partial unloads. - logger.warning("Partial goods unload, expected: " + amount + if (logger.isLoggable(Level.WARNING)) logger.warning("Partial goods unload, expected: " + amount + ", got: " + (oldAmount - newAmount)); result = false; } - logger.fine("Unloaded " + amount + " " + type + if (logger.isLoggable(Level.FINE)) logger.fine("Unloaded " + amount + " " + type + " from " + oldAmount + " leaving " + newAmount + " off of " + carrier + " at " + carrier.getLocation()); } @@ -307,7 +308,7 @@ public boolean joinTransport(Unit carrier, Direction direction) { getAIMain().getAIColony(colony).removeExportGoods(this); } } - logger.fine("Loaded " + amount + " " + type.getSuffix() + if (logger.isLoggable(Level.FINE)) logger.fine("Loaded " + amount + " " + type.getSuffix() + " over " + oldAmount + " leaving " + (goodsAmount - amount) + " onto " + carrier + " at " + carrier.getLocation()); return !failed; @@ -344,9 +345,8 @@ public void dispose() { if (destination instanceof Colony) { AIColony aic = getAIMain().getAIColony((Colony)destination); if (aic != null) aic.removeExportGoods(this); - } else if (destination instanceof Europe) { - // Nothing to remove. - } else { + } else if (!(destination instanceof Europe) + && logger.isLoggable(Level.WARNING)) { logger.warning("Unknown type of destination: " + destination); } destination = null; diff --git a/src/net/sf/freecol/server/ai/AIMain.java b/src/net/sf/freecol/server/ai/AIMain.java index b6025e5175..cf205b69af 100644 --- a/src/net/sf/freecol/server/ai/AIMain.java +++ b/src/net/sf/freecol/server/ai/AIMain.java @@ -240,7 +240,9 @@ public boolean removeAIObject(String id) { synchronized (aiObjects) { result = aiObjects.remove(id) != null; } - if (result) logger.finest("Removed AI object: " + id); + if (result) { + if (logger.isLoggable(Level.FINEST)) logger.finest("Removed AI object: " + id); + } return result; } @@ -425,7 +427,7 @@ public void setFreeColGameObject(String id, FreeColGameObject fcgo) { // No point doing anything with the object yet, as we // need the player type before we can create the // right class of AI player. - logger.info("Temporarily ignoring incomplete AI player: " + if (logger.isLoggable(Level.INFO)) logger.info("Temporarily ignoring incomplete AI player: " + fcgo.getId()); } else if (player.isIndian()) { aio = new NativeAIPlayer(this, player); @@ -469,7 +471,7 @@ public void ownerChanged(FreeColGameObject source, Player oldOwner, Player newOwner) { AIObject ao = getAIObject(source); if (ao == null) return; - logger.finest("Owner changed for " + source.getId() + if (logger.isLoggable(Level.FINEST)) logger.finest("Owner changed for " + source.getId() + " with AI object: " + ao); AIPlayer oldAIOwner = getAIPlayer(oldOwner); @@ -546,13 +548,13 @@ protected void writeChildren(FreeColXMLWriter xw) throws XMLStreamException { try { if (aio.getId() == null) { - logger.warning("Null AI identifier for: " + if (logger.isLoggable(Level.WARNING)) logger.warning("Null AI identifier for: " + aio.getClass().getName()); } else { aio.toXML(xw); } - } catch (Exception e) { - logger.log(Level.WARNING, "Failed to write AI object: " + aio, + } catch (XMLStreamException e) { + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Failed to write AI object: " + aio, e); } } @@ -592,11 +594,16 @@ protected void readChild(FreeColXMLReader xr) throws XMLStreamException { // with the call to setInitialized(). AIObject aio = null; boolean indirect = false; - if (oid != null && (aio = getAIObject(oid)) != null) { - aio.readFromXML(xr); - aio.setInitialized(); + if (oid != null) { + aio = getAIObject(oid); + if (aio != null) { + aio.readFromXML(xr); + aio.setInitialized(); + return; + } + } - } else if (AIColony.TAG.equals(tag)) { + if (AIColony.TAG.equals(tag)) { aio = new AIColony(this, xr); } else if (AIGoods.TAG.equals(tag)) { @@ -637,7 +644,9 @@ protected void readChild(FreeColXMLReader xr) throws XMLStreamException { aio = new WorkerWish(this, xr); } else { - System.err.println("AT " + tag + " with " + oid); + if (logger.isLoggable(Level.WARNING)) { + logger.warning("AT " + tag + " with " + oid); + } indirect = true; super.readChild(xr); } @@ -647,12 +656,12 @@ protected void readChild(FreeColXMLReader xr) throws XMLStreamException { } } catch (XMLStreamException xse) { // Expected throw xse; - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { // Nothing above apparently tries to throw an exception // that can end up here, but that keeps changing and // this is a great place to resynchronize the reader // so keep this in place. - logger.log(Level.WARNING, "Exception reading AIObject: " + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Exception reading AIObject: " + tag + ", id=" + oid, e); final String mainTag = TAG; while (xr.moreTags() || !(xr.atTag(tag) || xr.atTag(mainTag))); diff --git a/src/net/sf/freecol/server/ai/AIPlayer.java b/src/net/sf/freecol/server/ai/AIPlayer.java index 95f0595e5d..ddfc3b52e4 100644 --- a/src/net/sf/freecol/server/ai/AIPlayer.java +++ b/src/net/sf/freecol/server/ai/AIPlayer.java @@ -227,7 +227,7 @@ protected List getAIUnits() { List aiUnits = new ArrayList<>(); for (Unit u : getPlayer().getUnitSet()) { if (u.isDisposed()) { - logger.warning("getAIUnits ignoring: " + u.getId()); + if (logger.isLoggable(Level.WARNING)) logger.warning("getAIUnits ignoring: " + u.getId()); continue; } AIUnit a = getAIUnit(u); @@ -238,7 +238,7 @@ protected List getAIUnits() { } aiUnits.add(a); } else { - logger.warning("Could not find the AIUnit for: " + if (logger.isLoggable(Level.WARNING)) logger.warning("Could not find the AIUnit for: " + u + " (" + u.getId() + ")"); } } @@ -281,7 +281,7 @@ protected void invoke(final Runnable runnable) { Thread thread = new Thread(runnable, FreeCol.SERVER_THREAD + "AIPlayer(" + getPlayer().getName() + ")"); thread.start(); - logger.finest("Started " + thread); + if (logger.isLoggable(Level.FINEST)) logger.finest("Started " + thread); } // Message.aiHandler support @@ -294,7 +294,7 @@ protected void invoke(final Runnable runnable) { public void chooseFoundingFatherHandler(List fathers) { FoundingFather ff = selectFoundingFather(fathers); if (ff == null) return; - logger.finest(getId() + " chose founding father: " + ff); + if (logger.isLoggable(Level.FINEST)) logger.finest(getId() + " chose founding father: " + ff); invoke(() -> { AIMessage.askChooseFoundingFather(this, fathers, ff); }); @@ -316,11 +316,11 @@ public void diplomacyHandler(FreeColGameObject our, case PROPOSE_TRADE: agreement.setStatus(this.acceptDiplomaticTrade(agreement)); sb.append(" -> ").append(agreement); - logger.fine(sb.toString()); + if (logger.isLoggable(Level.FINE)) logger.fine(sb.toString()); break; default: // Do not need to respond to others sb.append(" -> ignoring ").append(agreement.getStatus()); - logger.fine(sb.toString()); + if (logger.isLoggable(Level.FINE)) logger.fine(sb.toString()); return; } @@ -369,7 +369,7 @@ public void indianDemandHandler(Unit unit, Colony colony, GoodsType type, int amount, IndianDemandAction initial) { IndianDemandAction result = indianDemand(unit, colony, type, amount, initial); - logger.finest("AI handling native demand by " + unit + if (logger.isLoggable(Level.FINEST)) logger.finest("AI handling native demand by " + unit + " at " + colony + " result: " + initial + " -> " + result); if (result != IndianDemandAction.INDIAN_DEMAND_DONE) { invoke(() -> { @@ -423,10 +423,10 @@ public void monarchActionHandler(MonarchAction action, int tax) { break; default: - logger.finest("AI player ignoring monarch action " + action); + if (logger.isLoggable(Level.FINEST)) logger.finest("AI player ignoring monarch action " + action); return; } - logger.finest("AI player monarch action " + action + " = " + accept); + if (logger.isLoggable(Level.FINEST)) logger.finest("AI player monarch action " + action + " = " + accept); invoke(() -> { AIMessage.askMonarchAction(this, action, accept); @@ -441,7 +441,7 @@ public void monarchActionHandler(MonarchAction action, int tax) { */ public void nationSummaryHandler(Player other, NationSummary ns) { getPlayer().putNationSummary(other, ns); - logger.info("Updated nation summary of " + other.getSuffix() + if (logger.isLoggable(Level.INFO)) logger.info("Updated nation summary of " + other.getSuffix() + " for AI " + player.getSuffix()); } @@ -512,7 +512,7 @@ public void setCurrentPlayerHandler(Player currentPlayer) { invoke(() -> { try { startWorking(); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { logger.log(Level.SEVERE, "Unhandled exception from the AI. The AI's turn has been ended prematurely.", e); askServer().chat(currentPlayer, Messages.message("ai.chat.stoppedWorking")); } diff --git a/src/net/sf/freecol/server/ai/AIUnit.java b/src/net/sf/freecol/server/ai/AIUnit.java index 4abf9d8549..e3d87c4104 100644 --- a/src/net/sf/freecol/server/ai/AIUnit.java +++ b/src/net/sf/freecol/server/ai/AIUnit.java @@ -227,7 +227,7 @@ private void takeTransport() { AIUnit transport = getTransport(); if (transport != aiCarrier) { if (transport != null) { - logger.warning("Taking different transport: " + aiCarrier); + if (logger.isLoggable(Level.WARNING)) logger.warning("Taking different transport: " + aiCarrier); dropTransport(); } setTransport(aiCarrier); @@ -693,8 +693,8 @@ public boolean leaveTransport() { && (direction = tile.getDirection(path.next.getTile())) != null) { try { return leaveTransport(direction); - } catch (Exception e) { - logger.log(Level.WARNING, "Leave transport crash for " + } catch (IllegalStateException e) { + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Leave transport crash for " + this + "/" + unit.getMovesLeft(), e); } } diff --git a/src/net/sf/freecol/server/ai/Cargo.java b/src/net/sf/freecol/server/ai/Cargo.java index aa722efc36..a48013e7d2 100644 --- a/src/net/sf/freecol/server/ai/Cargo.java +++ b/src/net/sf/freecol/server/ai/Cargo.java @@ -121,16 +121,17 @@ public String initialize(TransportableAIObject t, Unit carrier, // Get the path to the destination, possibly allowing fallback // to a destination that at least improves matters. PathNode deliver = t.getDeliveryPath(carrier, tdst); - fallback = false; + boolean isFallback = false; if (deliver == null && allowFallback) { deliver = t.getIntermediatePath(carrier, tdst); - fallback = true; + isFallback = deliver != null; } if (deliver == null) { return "no-deliver " + t + "/" + carrier.toShortString() + " -> " + tdst.toShortString(); } + fallback = isFallback; // Where is the transportable collected? At the first // path node where it is on the carrier. @@ -153,11 +154,13 @@ public String initialize(TransportableAIObject t, Unit carrier, // Can the carrier reach the pickup point? If already // carrying this is obviously moot. PathNode collect = null; - if (!carrying - && (collect = carrier.findPath(this.cwait)) == null) { - return "no-collect " + t - + "/" + carrier.toShortString() - + " at " + this.cwait.toShortString(); + if (!carrying) { + collect = carrier.findPath(this.cwait); + if (collect == null) { + return "no-collect " + t + + "/" + carrier.toShortString() + + " at " + this.cwait.toShortString(); + } } // Where is the transportable dropped? At the drop node, @@ -727,7 +730,9 @@ public void readFromXML(AIMain aiMain, FreeColXMLReader xr) throws XMLStreamExce } /** - * {@inheritDoc} + * Gets the XML tag name for serialization. + * + * @return The XML tag name. */ public String getXMLTagName() { return TAG; } diff --git a/src/net/sf/freecol/server/ai/ColonyPlan.java b/src/net/sf/freecol/server/ai/ColonyPlan.java index 0c962b2f88..5a521d08ec 100644 --- a/src/net/sf/freecol/server/ai/ColonyPlan.java +++ b/src/net/sf/freecol/server/ai/ColonyPlan.java @@ -55,6 +55,7 @@ import net.sf.freecol.common.model.WorkLocation; import static net.sf.freecol.common.util.CollectionUtils.*; import net.sf.freecol.common.util.LogBuilder; +import java.util.logging.Level; /** @@ -342,7 +343,8 @@ public void refine(BuildableType build, LogBuilder lb) { int n = 0, idx = produce.indexOf(g); for (GoodsType type = g.getInputType(); type != null; type = type.getInputType()) { - if ((wls = suppressed.get(type)) == null) break; + wls = suppressed.get(type); + if (wls == null) break; if (colony.getGoodsCount(type) >= GoodsContainer.CARGO_SIZE/2) break; n += wls.size(); @@ -472,7 +474,7 @@ private void updateGoodsTypeLists(Map> pro } else if (g.isFarmed()) { otherRawGoodsTypes.add(g); } else { // Not interested in this goods type. Should not happen. - logger.warning("Ignoring goods type " + g + if (logger.isLoggable(Level.WARNING)) logger.warning("Ignoring goods type " + g + " at " + colony.getName()); production.remove(g); } @@ -612,12 +614,10 @@ private boolean prioritize(BuildableType type, buildPlans.add(new BuildPlan(type, weight, support)); return true; } - if (bp.weight * bp.support < weight * support) { - bp.weight = weight; - bp.support = support; - return true; - } - return false; + if (bp.weight * bp.support >= weight * support) return false; + bp.weight = weight; + bp.support = support; + return true; } /** @@ -778,7 +778,7 @@ private void updateBuildableTypes() { } if (!expectFail && findBuildPlan(type) == null) { - logger.warning("No building priority found for: " + type); + if (logger.isLoggable(Level.WARNING)) logger.warning("No building priority found for: " + type); } } @@ -1092,13 +1092,12 @@ protected static Unit getBestWorker(WorkLocation wl, GoodsType goodsType, * Equips a unit for a role, trying all possibilities if a military role * was called for. * - * @param spec The {@code Specification} defining the roles. * @param unit The {@code Unit} to equip if possible. * @param role The {@code Role} for the unit to take. * @param colony The {@code Colony} storing the equipment. * @return True if the unit was equipped. */ - private static boolean fullEquipUnit(Specification spec, Unit unit, Role role, Colony colony) { + private static boolean fullEquipUnit(Unit unit, Role role, Colony colony) { return colony.equipForRole(unit, role, role.getMaximumCount()); } @@ -1155,14 +1154,14 @@ public Colony assignWorkers(List workers, boolean preferScout, Role role = outdoorRole; if (role == null) { for (Role r : u.getSortedMilitaryRoles()) { - if (u.getType() == r.getExpertUnit() && fullEquipUnit(spec(), u, r, col)) { + if (u.getType() == r.getExpertUnit() && fullEquipUnit(u, r, col)) { workers.remove(u); lb.add(u.getId(), "(", u.getType().getSuffix(), ") -> ", r.getSuffix(), "\n"); break; } } - } else if (u.getType() == role.getExpertUnit() && fullEquipUnit(spec(), u, role, col)) { + } else if (u.getType() == role.getExpertUnit() && fullEquipUnit(u, role, col)) { workers.remove(u); lb.add(u.getId(), "(", u.getType().getSuffix(), ") -> ", role.getSuffix(), "\n"); @@ -1194,7 +1193,7 @@ public Colony assignWorkers(List workers, boolean preferScout, continue; } for (Role role : u.getSortedMilitaryRoles()) { - if (role != null && fullEquipUnit(spec(), u, role, col)) { + if (role != null && fullEquipUnit(u, role, col)) { workers.remove(u); lb.add(u.getId(), "(", u.getType().getSuffix(), ") -> ", u.getRoleSuffix(), "\n"); @@ -1221,9 +1220,8 @@ public Colony assignWorkers(List workers, boolean preferScout, // Try to produce something. wlps = workPlans; while (!produce.isEmpty()) { - if ((wlp = findPlan(produce.get(0), workPlans)) != null) { - break; // Found a plan to try. - } + wlp = findPlan(produce.get(0), workPlans); + if (wlp != null) break; // Found a plan to try. produce.remove(0); // Can not produce this goods type } } @@ -1246,7 +1244,6 @@ public Colony assignWorkers(List workers, boolean preferScout, String err = null; goodsType = wlp.getGoodsType(); wl = col.getCorresponding(wlp.getWorkLocation()); - best = null; lb.add(" ", LogBuilder.wide(2, col.getUnitCount()), ": ", LogBuilder.wide(-15, goodsType.getSuffix()), "@", LogBuilder.wide(25, locationDescription(wl)), @@ -1256,8 +1253,9 @@ public Colony assignWorkers(List workers, boolean preferScout, err = "can not be worked"; } else if (wl.isFull()) { err = "full"; - } else if ((best = ColonyPlan.getBestWorker(wl, goodsType, - workers)) == null) { + } + best = ColonyPlan.getBestWorker(wl, goodsType, workers); + if (best == null) { err = "no worker found"; } if (err != null) { @@ -1427,7 +1425,9 @@ public Colony assignWorkers(List workers, boolean preferScout, lb.add(" Swapped ", u1.getId(), "(", u1.getType().getSuffix(), ") for ", other, "\n"); expertIterator.remove(); - } else if ((other = u1.trySwapExpert(nonExperts)) != null) { + } else { + other = u1.trySwapExpert(nonExperts); + if (other == null) continue; lb.add(" Swapped ", u1.getId(), "(", u1.getType().getSuffix(), ") for ", other, "\n"); expertIterator.remove(); @@ -1450,7 +1450,7 @@ public Colony assignWorkers(List workers, boolean preferScout, for (Unit u : sort(workers, soldierComparator)) { if (u.getSkillLevel() > 0) continue; for (Role role : u.getSortedMilitaryRoles()) { - if (fullEquipUnit(spec(), u, role, col)) { + if (fullEquipUnit(u, role, col)) { lb.add(" ", u.getId(), "(", u.getType().getSuffix(), ") -> ", u.getRoleSuffix(), "\n"); workers.remove(u); @@ -1459,7 +1459,7 @@ public Colony assignWorkers(List workers, boolean preferScout, } } for (Unit u : transform(col.getUnits(), u -> !u.hasDefaultRole())) { - logger.warning("assignWorkers bogus role for " + u); + if (logger.isLoggable(Level.WARNING)) logger.warning("assignWorkers bogus role for " + u); u.changeRole(spec().getDefaultRole(), 0); } diff --git a/src/net/sf/freecol/server/ai/EuropeanAIPlayer.java b/src/net/sf/freecol/server/ai/EuropeanAIPlayer.java index 40d0b8c2e7..82deed9ce6 100644 --- a/src/net/sf/freecol/server/ai/EuropeanAIPlayer.java +++ b/src/net/sf/freecol/server/ai/EuropeanAIPlayer.java @@ -312,8 +312,8 @@ public boolean isAggressive() { * TODO: We need to decide where to put AI behavior parameters so that mod * authors can customize the AI feel. Perhaps just in the specification? */ - return getPlayer().getNation().getType().getId().equals("model.nationType.conquest") - || getPlayer().getNation().getType().getId().equals("model.nationType.immigration"); + return "model.nationType.conquest".equals(getPlayer().getNation().getType().getId()) + || "model.nationType.immigration".equals(getPlayer().getNation().getType().getId()); } /** @@ -322,7 +322,7 @@ public boolean isAggressive() { * @return {@code true} if native settlements should be targeted by this player. */ public boolean isLikesAttackingNatives() { - return getPlayer().getNation().getType().getId().equals("model.nationType.conquest"); + return "model.nationType.conquest".equals(getPlayer().getNation().getType().getId()); } /** @@ -365,7 +365,7 @@ private void removeAIColony(AIColony aic) { PioneeringMission pm = aiu.getMission(PioneeringMission.class); if (pm != null) { if (tips.contains(pm.getTileImprovementPlan())) { - logger.info(pm + " collapses with loss of " + colony); + if (logger.isLoggable(Level.INFO)) logger.info(pm + " collapses with loss of " + colony); aiu.changeMission(null); } continue; @@ -374,7 +374,7 @@ private void removeAIColony(AIColony aic) { wm = aiu.getMission(WishRealizationMission.class); if (wm != null) { if (wishes.contains(wm.getWish())) { - logger.info(wm + " collapses with loss of " + colony); + if (logger.isLoggable(Level.INFO)) logger.info(wm + " collapses with loss of " + colony); aiu.changeMission(null); } continue; @@ -451,7 +451,8 @@ private void initializeMissions(LogBuilder lb) { if (target == null) { throw new RuntimeException("Initial colony fail: " + u); } - if ((m = getBuildColonyMission(aiu, target)) != null) { + m = getBuildColonyMission(aiu, target); + if (m != null) { lb.add(m, ", "); } } @@ -473,7 +474,8 @@ private void initializeMissions(LogBuilder lb) { lb.mark(); for (AIUnit aiu : aiUnits) { if (aiu.hasMission()) continue; - if ((m = getSimpleMission(aiu)) != null) lb.add(m, ", "); + m = getSimpleMission(aiu); + if (m != null) lb.add(m, ", "); } if (lb.grew("\n Backup: ")) lb.shrink(", "); } @@ -488,9 +490,9 @@ public void cheatGold(int amount, LogBuilder lb) { final Player player = getPlayer(); int gold = player.getGold(); if (gold < amount) { - amount -= gold; - player.modifyGold(amount); - lb.add("added ", amount, " gold"); + int delta = amount - gold; + player.modifyGold(delta); + lb.add("added ", delta, " gold"); } player.logCheat(amount + " gold"); } @@ -605,12 +607,14 @@ && pioneersNeeded() > 0 cheatGold(cost, lb); AIUnit aiu; if (bestWish == null) { - if ((aiu = recruitAIUnitInEurope(-1)) != null) { + aiu = recruitAIUnitInEurope(-1); + if (aiu != null) { // let giveNormalMissions look after the mission lb.add(" to recruit ", aiu.getUnit(), ", "); } } else { - if ((aiu = trainAIUnitInEurope(bestWish.getUnitType())) != null) { + aiu = trainAIUnitInEurope(bestWish.getUnitType()); + if (aiu != null) { Mission m = getWishRealizationMission(aiu, bestWish); if (m != null) { lb.add(" to train for ", m, ", "); @@ -713,7 +717,7 @@ && pioneersNeeded() > 0 // Only cheat carriers if they have work to do. int nCarrier = (nNavalCarrier > 0) ? transportNavalUnitCheatPercent : -1; - if (randoms[cheatIndex++] < nCarrier) { + if (randoms[cheatIndex] < nCarrier) { cheatUnit(transform(spec.getUnitTypeList(), ut -> ut.hasAbility(Ability.NAVAL_UNIT) && ut.isAvailableTo(player) @@ -886,7 +890,7 @@ public void buildTipMap(LogBuilder lb) { aic.removeTileImprovementPlan(tip); tip.dispose(); } else if (tip.getTarget() == null) { - logger.warning("No target for tip: " + tip); + if (logger.isLoggable(Level.WARNING)) logger.warning("No target for tip: " + tip); } else { TileImprovementPlan other = tipMap.get(tip.getTarget()); if (other == null || other.getValue() < tip.getValue()) { @@ -1282,7 +1286,8 @@ private WorkerWish getBestWorkerWish(AIUnit aiUnit, UnitType unitType) { final Unit carrier = aiUnit.getUnit(); WorkerWish carried = null; WorkerWish other = null; - double bestCarriedValue = -1.0, bestOtherValue = -1.0; + double bestCarriedValue = -1.0; + double bestOtherValue = -1.0; for (WorkerWish w : wishes) { Location dest = w.getDestination(); if (dest == null) continue; // Defend against crash @@ -1438,7 +1443,9 @@ private int buildersNeeded() { Player player = getPlayer(); if (!player.canBuildColonies()) return 0; - int nColonies = 0, nPorts = 0, nColonySize1 = 0; + int nColonies = 0; + int nPorts = 0; + int nColonySize1 = 0; for (Settlement settlement : player.getSettlementList()) { nColonies++; if (settlement.isConnectedPort()) nPorts++; @@ -1480,12 +1487,13 @@ private AIUnit recruitAIUnitInEurope(int slot) { if (europe == null) return null; int n = europe.getUnitCount(); final String selectAbility = Ability.SELECT_RECRUIT; - if (!Europe.MigrationType.validMigrantSlot(slot)) { - slot = (getPlayer().hasAbility(selectAbility)) + int selectedSlot = slot; + if (!Europe.MigrationType.validMigrantSlot(selectedSlot)) { + selectedSlot = (getPlayer().hasAbility(selectAbility)) ? Europe.MigrationType.getDefaultSlot() : Europe.MigrationType.getUnspecificSlot(); } - if (AIMessage.askEmigrate(this, slot) + if (AIMessage.askEmigrate(this, selectedSlot) && europe.getUnitCount() == n+1) { aiUnit = getAIUnit(europe.getUnitList().get(n)); if (aiUnit != null) addAIUnit(aiUnit); @@ -1711,7 +1719,8 @@ protected void giveNormalMissions(LogBuilder lb, List aiUnits) { } else if (unit.isDamaged()) { // Damaged units must wait if (!(m instanceof IdleAtSettlementMission)) { - if ((m = getIdleAtSettlementMission(aiUnit)) != null) { + m = getIdleAtSettlementMission(aiUnit); + if (m != null) { lb.add(", ", m); } } @@ -1723,7 +1732,7 @@ protected void giveNormalMissions(LogBuilder lb, List aiUnits) { if (!(m instanceof WorkInsideColonyMission) && (m = getWorkInsideColonyMission(aiUnit, aiMain.getAIColony(colony))) != null) { - logger.warning(aiUnit + " should WorkInsideColony at " + if (logger.isLoggable(Level.WARNING)) logger.warning(aiUnit + " should WorkInsideColony at " + colony.getName()); lb.add(", ", m); updateTransport(aiUnit, oldTarget, lb); @@ -1788,10 +1797,10 @@ protected void giveNormalMissions(LogBuilder lb, List aiUnits) { if (bcm != null && !player.hasSettlements()) { final Location bcmTarget = bcm.getTarget(); for (AIUnit aiUnit : sort(aiUnits, builderComparator)) { - final Location oldTarget = ((m = aiUnit.getMission()) == null) - ? null : m.getTarget(); - if ((m = getBuildColonyMission(aiUnit, bcmTarget)) == null) - continue; + m = aiUnit.getMission(); + final Location oldTarget = (m == null) ? null : m.getTarget(); + m = getBuildColonyMission(aiUnit, bcmTarget); + if (m == null) continue; lb.add(", ", m); updateTransport(aiUnit, oldTarget, lb); done.add(aiUnit); @@ -1818,10 +1827,10 @@ protected void giveNormalMissions(LogBuilder lb, List aiUnits) { if (tries > MAX_BUILDING_MISSION_TRIES) { break; } - final Location oldTarget = ((m = aiUnit.getMission()) == null) - ? null : m.getTarget(); - if ((m = getBuildColonyMission(aiUnit, null)) == null) - continue; + m = aiUnit.getMission(); + final Location oldTarget = (m == null) ? null : m.getTarget(); + m = getBuildColonyMission(aiUnit, null); + if (m == null) continue; lb.add(", ", m); updateTransport(aiUnit, oldTarget, lb); done.add(aiUnit); @@ -1834,10 +1843,11 @@ protected void giveNormalMissions(LogBuilder lb, List aiUnits) { } if (nScouts > 0) { for (AIUnit aiUnit : sort(aiUnits, scoutComparator)) { - final Location oldTarget = ((m = aiUnit.getMission()) == null) - ? null : m.getTarget(); + m = aiUnit.getMission(); + final Location oldTarget = (m == null) ? null : m.getTarget(); final Unit unit = aiUnit.getUnit(); - if ((m = getScoutingMission(aiUnit)) == null) continue; + m = getScoutingMission(aiUnit); + if (m == null) continue; lb.add(", ", m); updateTransport(aiUnit, oldTarget, lb); done.add(aiUnit); @@ -1851,9 +1861,10 @@ protected void giveNormalMissions(LogBuilder lb, List aiUnits) { if (nPioneers > 0) { for (AIUnit aiUnit : sort(aiUnits, pioneerComparator)) { final Unit unit = aiUnit.getUnit(); - final Location oldTarget = ((m = aiUnit.getMission()) == null) - ? null : m.getTarget(); - if ((m = getPioneeringMission(aiUnit, null)) == null) continue; + m = aiUnit.getMission(); + final Location oldTarget = (m == null) ? null : m.getTarget(); + m = getPioneeringMission(aiUnit, null); + if (m == null) continue; lb.add(", ", m); updateTransport(aiUnit, oldTarget, lb); done.add(aiUnit); @@ -1868,9 +1879,10 @@ protected void giveNormalMissions(LogBuilder lb, List aiUnits) { // Give the remaining land units a valid mission. for (AIUnit aiUnit : aiUnits) { final Unit unit = aiUnit.getUnit(); - final Location oldTarget = ((m = aiUnit.getMission()) == null) - ? null : m.getTarget(); - if ((m = getSimpleMission(aiUnit)) == null) continue; + m = aiUnit.getMission(); + final Location oldTarget = (m == null) ? null : m.getTarget(); + m = getSimpleMission(aiUnit); + if (m == null) continue; lb.add(", ", m); updateTransport(aiUnit, oldTarget, lb); reasons.put(unit, "New-Land"); @@ -1884,9 +1896,10 @@ protected void giveNormalMissions(LogBuilder lb, List aiUnits) { // transport missions. for (AIUnit aiUnit : navalUnits) { final Unit unit = aiUnit.getUnit(); - Mission old = ((m = aiUnit.getMission()) != null && m.isValid()) - ? m : null; - if ((m = getSimpleMission(aiUnit)) == null) continue; + m = aiUnit.getMission(); + Mission old = (m != null && m.isValid()) ? m : null; + m = getSimpleMission(aiUnit); + if (m == null) continue; lb.add(", ", m, ((m == old) ? " (preserved)" : " (new)")); reasons.put(unit, "New-Naval"); done.add(aiUnit); @@ -1920,7 +1933,7 @@ protected void giveNormalMissions(LogBuilder lb, List aiUnits) { m = aiUnit.getMission(); final Location oldTarget = (m == null) ? null : m.getTarget(); if (m != null && m.isValid() && !m.isOneTime()) { - logger.warning("Trying fallback mission for unit " + unit + if (logger.isLoggable(Level.WARNING)) logger.warning("Trying fallback mission for unit " + unit + " with valid mission " + m + " reason " + reasons.get(unit)); continue; @@ -1931,7 +1944,8 @@ protected void giveNormalMissions(LogBuilder lb, List aiUnits) { if (ports == null) ports = player.getConnectedPortList(); Colony c = ports.remove(0); AIColony aic = aiMain.getAIColony(c); - if ((m = getWorkInsideColonyMission(aiUnit, aic)) != null) { + m = getWorkInsideColonyMission(aiUnit, aic); + if (m != null) { lb.add(", ", m); updateTransport(aiUnit, oldTarget, lb); reasons.put(unit, "To-work"); @@ -1940,7 +1954,8 @@ protected void giveNormalMissions(LogBuilder lb, List aiUnits) { } else if (m instanceof IdleAtSettlementMission) { reasons.put(unit, "Idle"); // already idle } else { - if ((m = getIdleAtSettlementMission(aiUnit)) != null) { + m = getIdleAtSettlementMission(aiUnit); + if (m != null) { lb.add(", ", m); updateTransport(aiUnit, oldTarget, lb); reasons.put(unit, "Idle"); @@ -1983,7 +1998,8 @@ protected void giveNormalMissions(LogBuilder lb, List aiUnits) { */ private Mission getSimpleMission(AIUnit aiUnit) { final Unit unit = aiUnit.getUnit(); - Mission m, ret; + Mission m; + Mission ret; final Mission old = ((m = aiUnit.getMission()) != null && m.isValid()) ? m : null; @@ -2020,7 +2036,7 @@ private Mission getSimpleMission(AIUnit aiUnit) { : (unit.hasAbility(Ability.REF_UNIT)) ? ((old instanceof UnitSeekAndDestroyMission) ? old : ((m = getSeekAndDestroyMission(aiUnit, 12)) != null) ? m - : (m = getWanderHostileMission(aiUnit))) + : getWanderHostileMission(aiUnit)) // Favour wish realization for expert units : (unit.isColonist() && unit.getSkillLevel() > 0 @@ -2076,12 +2092,13 @@ private Mission getBuildColonyMission(AIUnit aiUnit, Location target) { String reason = BuildColonyMission.invalidMissionReason(aiUnit); if (reason != null) return null; final Unit unit = aiUnit.getUnit(); - if (target == null) { - target = BuildColonyMission.findMissionTarget(aiUnit, + Location missionTarget = target; + if (missionTarget == null) { + missionTarget = BuildColonyMission.findMissionTarget(aiUnit, buildingRange, unit.isInEurope()); } - return (target == null) ? null - : new BuildColonyMission(getAIMain(), aiUnit, target); + return (missionTarget == null) ? null + : new BuildColonyMission(getAIMain(), aiUnit, missionTarget); } /** @@ -2165,18 +2182,19 @@ public Mission getMissionaryMission(AIUnit aiUnit) { */ public Mission getPioneeringMission(AIUnit aiUnit, Location target) { if (PioneeringMission.prepare(aiUnit) != null) return null; - if (target == null) { - target = PioneeringMission.findMissionTarget(aiUnit, + Location missionTarget = target; + if (missionTarget == null) { + missionTarget = PioneeringMission.findMissionTarget(aiUnit, pioneeringRange, true); } - if (target == null) { + if (missionTarget == null) { Unit unit = aiUnit.getUnit(); if (unit.isInEurope() || unit.getSettlement() != null) { aiUnit.equipForRole(getSpecification().getDefaultRole()); } return null; } - return new PioneeringMission(getAIMain(), aiUnit, target); + return new PioneeringMission(getAIMain(), aiUnit, missionTarget); } /** @@ -2188,11 +2206,12 @@ public Mission getPioneeringMission(AIUnit aiUnit, Location target) { */ public Mission getPrivateerMission(AIUnit aiUnit, Location target) { if (PrivateerMission.invalidMissionReason(aiUnit) != null) return null; - if (target == null) { - target = PrivateerMission.findMissionTarget(aiUnit, privateerRange, true); + Location missionTarget = target; + if (missionTarget == null) { + missionTarget = PrivateerMission.findMissionTarget(aiUnit, privateerRange, true); } - return (target == null) ? null - : new PrivateerMission(getAIMain(), aiUnit, target); + return (missionTarget == null) ? null + : new PrivateerMission(getAIMain(), aiUnit, missionTarget); } /** @@ -2236,12 +2255,13 @@ public Mission getTransportMission(AIUnit aiUnit) { private Mission getWishRealizationMission(AIUnit aiUnit, WorkerWish wish) { if (WishRealizationMission.invalidMissionReason(aiUnit) != null) return null; final Unit unit = aiUnit.getUnit(); - if (wish == null) { - wish = getBestWorkerWish(aiUnit, unit.getType()); + WorkerWish targetWish = wish; + if (targetWish == null) { + targetWish = getBestWorkerWish(aiUnit, unit.getType()); } - if (wish == null) return null; - consumeWorkerWish(aiUnit, wish); - return new WishRealizationMission(getAIMain(), aiUnit, wish); + if (targetWish == null) return null; + consumeWorkerWish(aiUnit, targetWish); + return new WishRealizationMission(getAIMain(), aiUnit, targetWish); } /** @@ -2253,14 +2273,16 @@ private Mission getWishRealizationMission(AIUnit aiUnit, WorkerWish wish) { */ public Mission getWorkInsideColonyMission(AIUnit aiUnit, AIColony aiColony) { - if (aiColony == null) { - aiColony = getAIColony(aiUnit.getUnit().getColony()); + AIColony targetColony = (aiColony != null) + ? aiColony + : getAIColony(aiUnit.getUnit().getColony()); + if (targetColony == null) { + return null; } - if (WorkInsideColonyMission.invalidMissionReason(aiUnit, aiColony.getColony()) != null) { + if (WorkInsideColonyMission.invalidMissionReason(aiUnit, targetColony.getColony()) != null) { return null; } - return (aiColony == null) ? null - : new WorkInsideColonyMission(getAIMain(), aiUnit, aiColony); + return new WorkInsideColonyMission(getAIMain(), aiUnit, targetColony); } @@ -2345,7 +2367,7 @@ public void startWorking() { buildWishMaps(lb); } cheat(lb); - buyUnitsInEurope(lb); + buyUnitsInEurope(); // Note order of operations below. We allow rearrange et al to run // even when there are no movable units left because this expedites @@ -2384,7 +2406,7 @@ public void startWorking() { workerWishes.clear(); } - private void buyUnitsInEurope(LogBuilder lb) { + private void buyUnitsInEurope() { /* * It seems that training/recruiting units, in other cases than cheating, * was removed from the code in 2012. This prevents the AI from actually @@ -2630,9 +2652,9 @@ protected List doMissions(List aiUnits, LogBuilder lb) { lb.add("\n ", unit, " "); try { aiu.doMission(lb); - } catch (Exception e) { + } catch (IllegalArgumentException | IllegalStateException e) { lb.add(", EXCEPTION: ", e.getMessage()); - logger.log(Level.WARNING, "doMissions failed for: " + aiu, e); + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "doMissions failed for: " + aiu, e); } if (unit.isDisposed() || unit.getLocation() == null) { aiu.dropTransport(); @@ -2677,7 +2699,8 @@ protected List doMissions(List aiUnits, LogBuilder lb) { */ @Override public int adjustMission(AIUnit aiUnit, PathNode path, Class type, int value) { - if (value > 0) { + int adjustedValue = value; + if (adjustedValue > 0) { if (type == DefendSettlementMission.class) { // Reduce value in proportion to the number of defenders. Location loc = DefendSettlementMission.extractTarget(aiUnit, path); @@ -2686,18 +2709,18 @@ public int adjustMission(AIUnit aiUnit, PathNode path, Class type, int value) } Colony colony = (Colony)loc; int defenders = getSettlementDefenders(colony); - value -= 25 * defenders; + adjustedValue -= 25 * defenders; // Reduce value according to the stockade level. if (colony.hasStockade()) { if (defenders > colony.getStockade().getLevel() + 1) { - value -= 100 * colony.getStockade().getLevel(); + adjustedValue -= 100 * colony.getStockade().getLevel(); } else { - value -= 20 * colony.getStockade().getLevel(); + adjustedValue -= 20 * colony.getStockade().getLevel(); } } } } - return value; + return adjustedValue; } /** @@ -2733,7 +2756,9 @@ public TradeStatus acceptDiplomaticTrade(DiplomaticTrade agreement) { // Synthetic event result = TradeStatus.PROPOSE_TRADE; } else { - int unacceptable = 0, value = 0, colonies = 0; + int unacceptable = 0; + int value = 0; + int colonies = 0; for (TradeItem item : agreement.getItems()) { if (item instanceof StanceTradeItem) { getNationSummary(other); // Freshen the name summary cache @@ -2867,7 +2892,7 @@ public NativeTradeAction handleTrade(NativeTradeAction action, */ @Override public boolean acceptTax(int tax) { - boolean ret = true; + boolean ret; LogBuilder lb = new LogBuilder(64); Goods toBeDestroyed = getPlayer().getMostValuableGoods(); lb.add("Tax demand to ", getPlayer().getName(), " of ", tax, "% with ", diff --git a/src/net/sf/freecol/server/ai/MissionAIPlayer.java b/src/net/sf/freecol/server/ai/MissionAIPlayer.java index 077e766f01..c8bfd34e6b 100644 --- a/src/net/sf/freecol/server/ai/MissionAIPlayer.java +++ b/src/net/sf/freecol/server/ai/MissionAIPlayer.java @@ -361,8 +361,8 @@ protected List doMissions(List aiUnits, LogBuilder lb) { lb.add("\n ", unit, " "); try { aiu.doMission(lb); - } catch (Exception e) { - logger.log(Level.WARNING, "doMissions failed for: " + aiu, e); + } catch (IllegalArgumentException | IllegalStateException e) { + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "doMissions failed for: " + aiu, e); } if (!unit.isDisposed() && unit.getMovesLeft() > 0) result.add(aiu); } diff --git a/src/net/sf/freecol/server/ai/NativeAIPlayer.java b/src/net/sf/freecol/server/ai/NativeAIPlayer.java index bee541552f..b79fc67955 100644 --- a/src/net/sf/freecol/server/ai/NativeAIPlayer.java +++ b/src/net/sf/freecol/server/ai/NativeAIPlayer.java @@ -256,12 +256,14 @@ public void secureIndianSettlement(final IndianSettlement is, AIUnit aiu = aiMain.getAIUnit(u); if (aiu == null) { units.remove(u); - } else if ((dm = aiu.getMission(DefendSettlementMission.class)) != null - && dm.getTarget() == is) { - defenders.add(u); - units.remove(u); - } else if (Mission.invalidNewMissionReason(aiu) != null) { - units.remove(u); + } else { + dm = aiu.getMission(DefendSettlementMission.class); + if (dm != null && dm.getTarget() == is) { + defenders.add(u); + units.remove(u); + } else if (Mission.invalidNewMissionReason(aiu) != null) { + units.remove(u); + } } } @@ -272,38 +274,46 @@ public void secureIndianSettlement(final IndianSettlement is, for (Tile t : is.getTile().getSurroundingTiles(is.getRadius() + 1)) { if (!t.isLand() || t.getUnitCount() == 0) { ; // Do nothing - } else if ((enemy = t.getFirstUnit().getOwner()) == player) { - // Its one of ours! - for (Unit u : t.getUnitList()) { - AIUnit aiu; - if (defenders.contains(u) || units.contains(u) - || (aiu = aiMain.getAIUnit(u)) == null) { - ; // Do nothing - } else if ((dm = aiu.getMission(DefendSettlementMission.class)) != null - && dm.getTarget() == is) { - defenders.add(u); - } else if (Mission.invalidNewMissionReason(aiu) == null) { - units.add(u); - } - } - } else if ((tension = is.getAlarm(enemy)) == null - || tension.getLevel().compareTo(Tension.Level.CONTENT) <= 0) { - ; // Not regarded as a threat } else { - // Evaluate the threat - double threshold, bonus, value = 0.0; - if (tension.getLevel().compareTo(Tension.Level.DISPLEASED) <= 0) { - threshold = 1.0; - bonus = 0.0f; + enemy = t.getFirstUnit().getOwner(); + if (enemy == player) { + // Its one of ours! + for (Unit u : t.getUnitList()) { + AIUnit aiu = aiMain.getAIUnit(u); + if (defenders.contains(u) || units.contains(u) + || aiu == null) { + ; // Do nothing + } else { + dm = aiu.getMission(DefendSettlementMission.class); + if (dm != null && dm.getTarget() == is) { + defenders.add(u); + } else if (Mission.invalidNewMissionReason(aiu) == null) { + units.add(u); + } + } + } } else { - threshold = 0.0; - bonus = (float)tension.getLevel().ordinal() - - Tension.Level.CONTENT.ordinal(); + tension = is.getAlarm(enemy); + if (tension == null + || tension.getLevel().compareTo(Tension.Level.CONTENT) <= 0) { + ; // Not regarded as a threat + } else { + // Evaluate the threat + double threshold, bonus, value = 0.0; + if (tension.getLevel().compareTo(Tension.Level.DISPLEASED) <= 0) { + threshold = 1.0; + bonus = 0.0f; + } else { + threshold = 0.0; + bonus = (float)tension.getLevel().ordinal() + - Tension.Level.CONTENT.ordinal(); + } + value += sumDouble(t.getUnits(), + u -> cm.getOffencePower(u, is) > threshold, + u -> cm.getOffencePower(u, is) + bonus); + if (value > 0.0) threats.put(t, value); + } } - value += sumDouble(t.getUnits(), - u -> cm.getOffencePower(u, is) > threshold, - u -> cm.getOffencePower(u, is) + bonus); - if (value > 0.0) threats.put(t, value); } } @@ -699,10 +709,12 @@ public IndianDemandAction indianDemand(Unit unit, Colony colony, AIUnit aiu; IndianDemandMission mission; if (unit.getOwner() == player) { // Its one of ours - if ((aiu = getAIUnit(unit)) != null // and its valid and demanding - && (mission = aiu.getMission(IndianDemandMission.class)) != null - && accept != IndianDemandAction.INDIAN_DEMAND_DONE) { - mission.setSucceeded(accept == IndianDemandAction.INDIAN_DEMAND_ACCEPT); + aiu = getAIUnit(unit); + if (aiu != null && accept != IndianDemandAction.INDIAN_DEMAND_DONE) { + mission = aiu.getMission(IndianDemandMission.class); + if (mission != null) { + mission.setSucceeded(accept == IndianDemandAction.INDIAN_DEMAND_ACCEPT); + } } } // Once we get here, the demand is settled diff --git a/src/net/sf/freecol/server/ai/REFAIPlayer.java b/src/net/sf/freecol/server/ai/REFAIPlayer.java index 5aec3ddb0b..789c9fda6d 100644 --- a/src/net/sf/freecol/server/ai/REFAIPlayer.java +++ b/src/net/sf/freecol/server/ai/REFAIPlayer.java @@ -119,13 +119,12 @@ public boolean check(Unit unit, PathNode pathNode) { = (u -> u.isOffensiveUnit() && u.isNaval() && !this.rebelNavy.contains(u)); Tile tile = pathNode.getTile(); - if (tile != null && !tile.isEmpty() - && !tile.isLand() - && this.rebel.owns(tile.getFirstUnit())) { - this.rebelNavy.addAll(transform(tile.getUnits(), pred)); - return true; + if (tile == null || tile.isEmpty() || tile.isLand() + || !this.rebel.owns(tile.getFirstUnit())) { + return false; } - return false; + this.rebelNavy.addAll(transform(tile.getUnits(), pred)); + return true; } }; @@ -334,12 +333,12 @@ public boolean initialize(boolean teleport) { final Unit unit = aiUnit.getUnit(); final Unit carrier = unit.getCarrier(); if (carrier == null) { - logger.warning("REF land unit not on a carrier: " + unit); + if (logger.isLoggable(Level.WARNING)) logger.warning("REF land unit not on a carrier: " + unit); return false; } final AIUnit aiCarrier = aiMain.getAIUnit(carrier); if (aiCarrier == null) { - logger.warning("REF naval unit missing: " + carrier); + if (logger.isLoggable(Level.WARNING)) logger.warning("REF naval unit missing: " + carrier); return false; } @@ -499,14 +498,16 @@ public boolean initialize(boolean teleport) { final Unit enemy = (ui.hasNext()) ? ui.next() : null; Tile start; if (enemy == null) { - if ((m = getWanderHostileMission(aiu)) != null) { + m = getWanderHostileMission(aiu); + if (m != null) { start = getRandomMember(logger, "REF patrol entry", entries, aiRandom); u.setEntryLocation(start); lb.add("\n Patrol from ", start, " with ", m); } } else { - if ((m = getSeekAndDestroyMission(aiu, enemy)) != null) { + m = getSeekAndDestroyMission(aiu, enemy); + if (m != null) { start = u.getBestEntryTile(enemy.getTile()); u.setEntryLocation(start); entries.add(start); @@ -547,9 +548,12 @@ private List requireTransports(int nt, List transports, && target.getTile() != null && aiu.getUnit().hasTile()) { naval.add(aiu); - } else if ((m = getTransportMission(aiu)) != null) { - lb.add(" notarget ", m); - result.add(aiu); + } else { + m = getTransportMission(aiu); + if (m != null) { + lb.add(" notarget ", m); + result.add(aiu); + } } } } @@ -564,7 +568,8 @@ private List requireTransports(int nt, List transports, for (AIUnit aiu : sort(naval, Comparator.comparingInt(targetDistance))) { int distance = targetDistance.applyAsInt(aiu); - if ((m = getTransportMission(aiu)) != null) { + m = getTransportMission(aiu); + if (m != null) { lb.add(" REQUIRED ", distance, " ", m); result.add(aiu); if (result.size() + transports.size() >= nt) break; @@ -656,7 +661,8 @@ && randomInt(logger, "REF defend " + colony.getName(), // Use free naval units as transports. for (AIUnit aiu : todo) { - if ((m = getTransportMission(aiu)) != null) { + m = getTransportMission(aiu); + if (m != null) { lb.add(" ", m); transports.add(aiu); } @@ -680,20 +686,22 @@ && randomInt(logger, "REF defend " + colony.getName(), if (target != null) { Integer count = targetMap.get(target); if (count == null) count = 0; - if (target instanceof Unit - && count < UNIT_USAD_THRESHOLD - && (m = getSeekAndDestroyMission(aiu, target)) != null) { - lb.add(" NEW-SEEK-", count, " ", m); - incrementMapCount(targetMap, target); - continue; - } else if (target instanceof Settlement - && (m = getSeekAndDestroyMission(aiu, target)) != null) { - lb.add(" NEW-SEEK ", m); - incrementMapCount(targetMap, target); - continue; - } else { - throw new RuntimeException("Bogus target: " + target); + if (target instanceof Unit && count < UNIT_USAD_THRESHOLD) { + m = getSeekAndDestroyMission(aiu, target); + if (m != null) { + lb.add(" NEW-SEEK-", count, " ", m); + incrementMapCount(targetMap, target); + continue; + } + } else if (target instanceof Settlement) { + m = getSeekAndDestroyMission(aiu, target); + if (m != null) { + lb.add(" NEW-SEEK ", m); + incrementMapCount(targetMap, target); + continue; + } } + throw new RuntimeException("Bogus target: " + target); } // Find units idle at a port @@ -701,8 +709,9 @@ && randomInt(logger, "REF defend " + colony.getName(), if (u.isInEurope()) { appendToMapList(idlers, player.getEurope(), aiu); continue; - } else if ((colony = u.getColony()) != null - && colony.isConnectedPort()) { + } + colony = u.getColony(); + if (colony != null && colony.isConnectedPort()) { appendToMapList(idlers, colony, aiu); continue; } @@ -710,11 +719,13 @@ && randomInt(logger, "REF defend " + colony.getName(), // Go defend the nearest colony needing defence Colony best = u.getClosestColony(map(getBadlyDefended(), AIColony::getColony)); - if (best != null - && (m = getDefendSettlementMission(aiu, best)) != null) { - lb.add(" GO-DEFEND-", best.getName(), " " , m); - incrementMapCount(targetMap, best); - continue; + if (best != null) { + m = getDefendSettlementMission(aiu, best); + if (m != null) { + lb.add(" GO-DEFEND-", best.getName(), " " , m); + incrementMapCount(targetMap, best); + continue; + } } // Just go defend the nearest port. Once there and enough @@ -723,11 +734,13 @@ && randomInt(logger, "REF defend " + colony.getName(), PathNode path = u.findOurNearestPort(); colony = (path == null) ? null : path.getLastNode().getTile().getColony(); - if (colony != null - && (m = getDefendSettlementMission(aiu, colony)) != null) { - lb.add(" GOTO-", colony.getName(), " " , m); - incrementMapCount(targetMap, colony); - continue; + if (colony != null) { + m = getDefendSettlementMission(aiu, colony); + if (m != null) { + lb.add(" GOTO-", colony.getName(), " " , m); + incrementMapCount(targetMap, colony); + continue; + } } // Just go somewhere and idle. @@ -746,15 +759,20 @@ && randomInt(logger, "REF defend " + colony.getName(), if (!tm.isEmpty()) continue; Unit u = aiu.getUnit(); Location key; - if (u.isInEurope() - && idlers.containsKey(key = player.getEurope())) { - appendToMapList(ready, key, aiu); - } else if ((key = u.getColony()) != null - && idlers.containsKey(key)) { - appendToMapList(ready, key, aiu); + if (u.isInEurope()) { + key = player.getEurope(); + if (idlers.containsKey(key)) { + appendToMapList(ready, key, aiu); + continue; + } } else { - todo.add(aiu); + key = u.getColony(); + if (key != null && idlers.containsKey(key)) { + appendToMapList(ready, key, aiu); + continue; + } } + todo.add(aiu); } // If there are idle units and carriers present at the @@ -795,13 +813,15 @@ && randomInt(logger, "REF defend " + colony.getName(), u -> u.hasAbility(Ability.REF_UNIT), u -> getAIUnit(u), toListNoNulls())); - if (found != null - && (m = found.getMission()) != null - && m.isValid() - && m instanceof UnitSeekAndDestroyMission - && m.getTarget() instanceof Colony) { - target = (Colony)m.getTarget(); - break; + if (found != null) { + m = found.getMission(); + if (m != null + && m.isValid() + && m instanceof UnitSeekAndDestroyMission + && m.getTarget() instanceof Colony) { + target = (Colony)m.getTarget(); + break; + } } } if (target == null) { @@ -817,12 +837,16 @@ && randomInt(logger, "REF defend " + colony.getName(), = aiCarrier.getMission(TransportMission.class); AIUnit aiu; for (Unit u : aiCarrier.getUnit().getUnitList()) { - if (u.hasAbility(Ability.REF_UNIT) - && (aiu = getAIUnit(u)) != null - && (m = getSeekAndDestroyMission(aiu, target)) != null) { - lb.add(" IDLER->", target, " ", m); - tm.queueTransportable(aiu, false, lb); - e.getValue().remove(aiu); + if (u.hasAbility(Ability.REF_UNIT)) { + aiu = getAIUnit(u); + if (aiu != null) { + m = getSeekAndDestroyMission(aiu, target); + if (m != null) { + lb.add(" IDLER->", target, " ", m); + tm.queueTransportable(aiu, false, lb); + e.getValue().remove(aiu); + } + } } } } @@ -894,7 +918,7 @@ && randomInt(logger, "REF defend " + colony.getName(), public void startWorking() { final Player player = getPlayer(); if (!player.isWorkForREF()) { - logger.warning("No work for REF: " + player); + if (logger.isLoggable(Level.WARNING)) logger.warning("No work for REF: " + player); return; } diff --git a/src/net/sf/freecol/server/ai/TransportableAIObject.java b/src/net/sf/freecol/server/ai/TransportableAIObject.java index db21dce53b..9c542672c7 100644 --- a/src/net/sf/freecol/server/ai/TransportableAIObject.java +++ b/src/net/sf/freecol/server/ai/TransportableAIObject.java @@ -211,9 +211,11 @@ public boolean changeTransport(AIUnit aiCarrier) { // Get off any current carrier unless it is the new one. Location now; Locatable l = getTransportLocatable(); - if (l != null && (now = l.getLocation()) instanceof Unit - && !(aiCarrier != null && aiCarrier.getUnit() == now)) { - if (!leaveTransport()) return false; + if (l != null) { + now = l.getLocation(); + if (now instanceof Unit + && !(aiCarrier != null && aiCarrier.getUnit() == now) + && !leaveTransport()) return false; } AIUnit old = getTransport(); diff --git a/src/net/sf/freecol/server/ai/colony/ColonyPlanner.java b/src/net/sf/freecol/server/ai/colony/ColonyPlanner.java index 2945c6ea21..236e9d3e22 100644 --- a/src/net/sf/freecol/server/ai/colony/ColonyPlanner.java +++ b/src/net/sf/freecol/server/ai/colony/ColonyPlanner.java @@ -26,6 +26,7 @@ * * Assumes perfect conditions like all bonus effect (SoL 100%, Henry Hudson etc) */ +@FunctionalInterface public interface ColonyPlanner { /** diff --git a/src/net/sf/freecol/server/ai/colony/plan/ProduceRawAndManufactoredUnstorableBuildingMaterialsStep.java b/src/net/sf/freecol/server/ai/colony/plan/ProduceRawAndManufactoredUnstorableBuildingMaterialsStep.java index b3b36011f4..67bf881790 100644 --- a/src/net/sf/freecol/server/ai/colony/plan/ProduceRawAndManufactoredUnstorableBuildingMaterialsStep.java +++ b/src/net/sf/freecol/server/ai/colony/plan/ProduceRawAndManufactoredUnstorableBuildingMaterialsStep.java @@ -54,7 +54,7 @@ final class ProduceRawAndManufactoredUnstorableBuildingMaterialsStep { private ProduceRawAndManufactoredUnstorableBuildingMaterialsStep() {} /** - * @ses {@link InitialSteps#produceRawAndManufactoredUnstorableBuildingMaterials(TentativeColonyPlan)} + * @see InitialSteps#produceRawAndManufactoredUnstorableBuildingMaterials(TentativeColonyPlan) */ static void execute(TentativeColonyPlan tcp) { final Specification s = tcp.getSpecification(); diff --git a/src/net/sf/freecol/server/ai/military/MilitaryCoordinator.java b/src/net/sf/freecol/server/ai/military/MilitaryCoordinator.java index b51c783f7d..04c8aaf6f4 100644 --- a/src/net/sf/freecol/server/ai/military/MilitaryCoordinator.java +++ b/src/net/sf/freecol/server/ai/military/MilitaryCoordinator.java @@ -168,9 +168,9 @@ public void determineMissions() { keepUnitsInColonies(defensiveMap.getColoniesExposedLand(), artilleryUnits, maxArtilleries(2)); placeUnitsInColonies(defensiveMap.getColoniesExposedLand(), dragoonUnits, maxDragoons(2)); - assignDefendClosestColony(unusedUnits); + assignDefendClosestColony(); if (!ourColonies.isEmpty()) { - transportMilitaryUnitsFromEurope(ourColonies.get(0), unusedUnits); + transportMilitaryUnitsFromEurope(ourColonies.get(0)); } assignWanderHostile(); } @@ -316,7 +316,7 @@ private void counterattackAllEnemyUnitsReachableInTurns(final Set dragoo } } - private void assignDefendClosestColony(Set militaryUnits) { + private void assignDefendClosestColony() { for (AIUnit unit : new HashSet<>(unusedUnits)) { final Mission mission = player.getDefendSettlementMission(unit, true, true); if (mission != null) { @@ -326,7 +326,7 @@ private void assignDefendClosestColony(Set militaryUnits) { } } - private void transportMilitaryUnitsFromEurope(AIColony destination, Set militaryUnits) { + private void transportMilitaryUnitsFromEurope(AIColony destination) { // TODO: Better method for transporting military units from Europe. for (AIUnit unit : new HashSet<>(unusedUnits)) { if (unit.getUnit().getTile() != null) { diff --git a/src/net/sf/freecol/server/ai/mission/BuildColonyMission.java b/src/net/sf/freecol/server/ai/mission/BuildColonyMission.java index 2de1247d95..64779dd5f5 100644 --- a/src/net/sf/freecol/server/ai/mission/BuildColonyMission.java +++ b/src/net/sf/freecol/server/ai/mission/BuildColonyMission.java @@ -436,7 +436,8 @@ public Mission doMission(LogBuilder lb) { // Find a real tile target? Location newTarget; - if ((newTarget = findMissionTarget(aiUnit, 5, false)) != null) { + newTarget = findMissionTarget(aiUnit, 5, false); + if (newTarget != null) { setTarget(newTarget); return lbRetarget(lb); } @@ -474,7 +475,7 @@ public Mission doMission(LogBuilder lb) { } else if (player.owns(tile)) { // Already ours, clear users Colony colony = (Colony)tile.getOwningSettlement(); if (colony != null) { - logger.warning("Building on colony tile: " + tile); + if (logger.isLoggable(Level.WARNING)) logger.warning("Building on colony tile: " + tile); return lbFail(lb, false, "building on colony tile ", tile); } } else { diff --git a/src/net/sf/freecol/server/ai/mission/DefendSettlementMission.java b/src/net/sf/freecol/server/ai/mission/DefendSettlementMission.java index 3c9c449703..823b977d91 100644 --- a/src/net/sf/freecol/server/ai/mission/DefendSettlementMission.java +++ b/src/net/sf/freecol/server/ai/mission/DefendSettlementMission.java @@ -145,12 +145,10 @@ private static GoalDecider getGoalDecider(final AIUnit aiUnit) { @Override public boolean check(Unit u, PathNode path) { int value = scorePath(aiUnit, path); - if (bestValue < value) { - bestValue = value; - bestPath = path; - return true; - } - return false; + if (bestValue >= value) return false; + bestValue = value; + bestPath = path; + return true; } }; } @@ -163,8 +161,9 @@ public boolean check(Unit u, PathNode path) { * @param deferOK Enables deferring to a fallback colony. * @return A path to the new target, or null if none found. */ + @SuppressWarnings("PMD.UnusedFormalParameter") private static PathNode findTargetPath(AIUnit aiUnit, int range, - @SuppressWarnings("unused") boolean deferOK) { + boolean deferOK) { if (invalidAIUnitReason(aiUnit) != null) return null; final Unit unit = aiUnit.getUnit(); final Location start = unit.getPathStartLocation(); @@ -343,7 +342,7 @@ public Mission doMission(LogBuilder lb) { // Change to supporting the settlement if the size is marginal. final AIMain aiMain = getAIMain(); final AIUnit aiUnit = getAIUnit(); - Mission m = null; + Mission m; if (getTarget() instanceof Colony) { Colony colony = (Colony)getTarget(); if (unit.isInColony() @@ -410,12 +409,11 @@ logger, getAIRandom())) { double weDefend = cm.getDefencePower(enemyUnit, unit); double difference = weAttack / (weAttack + enemyDefend) - enemyAttack / (enemyAttack + weDefend); - if (difference > bestDifference) { - if (difference > 0 || weAttack > enemyDefend) { - bestDifference = difference; - bestTarget = enemyUnit; - bestDirection = d; - } + if (difference > bestDifference + && (difference > 0 || weAttack > enemyDefend)) { + bestDifference = difference; + bestTarget = enemyUnit; + bestDirection = d; } } } diff --git a/src/net/sf/freecol/server/ai/mission/EscortUnitMission.java b/src/net/sf/freecol/server/ai/mission/EscortUnitMission.java index 4bd3ab9e2c..b446726552 100644 --- a/src/net/sf/freecol/server/ai/mission/EscortUnitMission.java +++ b/src/net/sf/freecol/server/ai/mission/EscortUnitMission.java @@ -34,6 +34,7 @@ import net.sf.freecol.server.ai.AIMain; import net.sf.freecol.server.ai.AIMessage; import net.sf.freecol.server.ai.AIUnit; +import java.util.logging.Level; /** @@ -236,7 +237,7 @@ public Mission doMission(LogBuilder lb) { final Tile unitTile = getUnit().getTile(); Direction d = unitTile.getDirection(currentTarget.getTile()); if (d == null) { - logger.warning("SDDM bogus " + mt + " with " + getUnit() + if (logger.isLoggable(Level.WARNING)) logger.warning("SDDM bogus " + mt + " with " + getUnit() + " from " + unitTile + " to " + currentTarget + " at " + currentTarget.getTile()); return lbWait(lb); diff --git a/src/net/sf/freecol/server/ai/mission/Mission.java b/src/net/sf/freecol/server/ai/mission/Mission.java index ac2b251850..fe805a97a1 100644 --- a/src/net/sf/freecol/server/ai/mission/Mission.java +++ b/src/net/sf/freecol/server/ai/mission/Mission.java @@ -59,6 +59,7 @@ import net.sf.freecol.server.ai.EuropeanAIPlayer; import net.sf.freecol.server.ai.MissionAIPlayer; import net.sf.freecol.server.ai.TransportableAIObject; +import java.util.logging.Level; /** @@ -299,7 +300,8 @@ public static String invalidTransportableReason(TransportableAIObject t) { if (checkSrc) { Settlement s; - if ((loc = t.getTransportSource()) == null) { + loc = t.getTransportSource(); + if (loc == null) { return "transportable-source-missing-" + t; } else if (((FreeColGameObject)loc).isDisposed()) { return "transportable-source-disposed"; @@ -741,70 +743,76 @@ protected MoveType travelToTarget(Location target, CostDecider costDecider, PathNode ownPath; int pathTurns, ownTurns; - if ((tm = aiCarrier.getMission(TransportMission.class)) == null) { + tm = aiCarrier.getMission(TransportMission.class); + if (tm == null) { // Carrier has no transport mission?!? Bogus. lb.add(", had bogus carrier ", aiCarrier.getUnit()); - logger.warning(unit + " has transport " + aiCarrier + if (logger.isLoggable(Level.WARNING)) logger.warning(unit + " has transport " + aiCarrier + " without transport mission"); aiUnit.dropTransport(); aiCarrier = null; - } else if ((pick = tm.getTransportTarget(aiUnit)) == null) { - // No collection point for this unit? Bogus. - lb.add(", had bogus transport on ", aiCarrier.getUnit()); - logger.warning(unit + " has transport " + aiCarrier - + " with transport mission but null transport target\n" - + tm.toFullString()); - aiUnit.dropTransport(); - aiCarrier = null; - - } else if (Map.isSameLocation(pick, unit.getLocation())) { - // Waiting for the carrier at the collection point. - waiting = true; - - } else if ((path = unit.findPath(unit.getLocation(), pick, - null, costDecider, null)) == null) { - // No path to the collection point. - lbAt(lb); - lb.add(", no path to meet ", aiCarrier.getUnit(), - " at ", pick); - path = unit.findPath(unit.getLocation(), target, - null, costDecider, null); - if (path == null) { - // Unable to fall back to going direct. - // Return failure in the hope that it is a - // transient blockage. - return MoveType.MOVE_NO_TILE; - } - // Fall back to going direct to the target. - lb.add(", dropped carrier"); - aiUnit.dropTransport(); - aiCarrier = null; - useTransport = false; - - } else if ((ownPath = unit.findPath(unit.getLocation(), - target, null, costDecider, null)) == null - || (ownTurns = ownPath.getTotalTurns()) - > (pathTurns = path.getTotalTurns())) { - // Either there is no direct path to the target or - // a path exists but takes longer than using the - // carrier. This confirms that it is not only - // possible to travel to the collection point, it - // is also the best plan. - MoveType ret = followMapPath(path.next, lb); - if (ret != MoveType.MOVE) return ret; - waiting = true; // Arrived for collection. - } else { - // It is quicker to cancel the transport and go to - // the target directly. - lb.add(", dropping carrier", aiCarrier.getUnit(), - " as it is faster (", ownTurns, "<", pathTurns, - " without it"); - aiUnit.dropTransport(); - aiCarrier = null; - path = ownPath; - useTransport = false; + pick = tm.getTransportTarget(aiUnit); + if (pick == null) { + // No collection point for this unit? Bogus. + lb.add(", had bogus transport on ", aiCarrier.getUnit()); + if (logger.isLoggable(Level.WARNING)) logger.warning(unit + " has transport " + aiCarrier + + " with transport mission but null transport target\n" + + tm.toFullString()); + aiUnit.dropTransport(); + aiCarrier = null; + } else if (Map.isSameLocation(pick, unit.getLocation())) { + // Waiting for the carrier at the collection point. + waiting = true; + } else { + path = unit.findPath(unit.getLocation(), pick, + null, costDecider, null); + if (path == null) { + // No path to the collection point. + lbAt(lb); + lb.add(", no path to meet ", aiCarrier.getUnit(), + " at ", pick); + path = unit.findPath(unit.getLocation(), target, + null, costDecider, null); + if (path == null) { + // Unable to fall back to going direct. + // Return failure in the hope that it is a + // transient blockage. + return MoveType.MOVE_NO_TILE; + } + // Fall back to going direct to the target. + lb.add(", dropped carrier"); + aiUnit.dropTransport(); + aiCarrier = null; + useTransport = false; + } else { + ownPath = unit.findPath(unit.getLocation(), + target, null, costDecider, null); + if (ownPath == null + || (ownTurns = ownPath.getTotalTurns()) + > (pathTurns = path.getTotalTurns())) { + // Either there is no direct path to the target or + // a path exists but takes longer than using the + // carrier. This confirms that it is not only + // possible to travel to the collection point, it + // is also the best plan. + MoveType ret = followMapPath(path.next, lb); + if (ret != MoveType.MOVE) return ret; + waiting = true; // Arrived for collection. + } else { + // It is quicker to cancel the transport and go to + // the target directly. + lb.add(", dropping carrier", aiCarrier.getUnit(), + " as it is faster (", ownTurns, "<", pathTurns, + " without it"); + aiUnit.dropTransport(); + aiCarrier = null; + path = ownPath; + useTransport = false; + } + } + } } if (waiting) { diff --git a/src/net/sf/freecol/server/ai/mission/PioneeringMission.java b/src/net/sf/freecol/server/ai/mission/PioneeringMission.java index 06644246b0..e0475b660a 100644 --- a/src/net/sf/freecol/server/ai/mission/PioneeringMission.java +++ b/src/net/sf/freecol/server/ai/mission/PioneeringMission.java @@ -266,12 +266,10 @@ private static GoalDecider getGoalDecider(final AIUnit aiUnit, @Override public boolean check(Unit u, PathNode path) { int value = scorePath(aiUnit, path); - if (bestValue < value) { - bestValue = value; - bestPath = path; - return true; - } - return false; + if (bestValue >= value) return false; + bestValue = value; + bestPath = path; + return true; } }; return (deferOK) ? GoalDeciders.getComposedGoalDecider(false, gd, @@ -722,7 +720,8 @@ && invalidTargetReason(getTarget(), player) == null) { aiPlayer.removeTileImprovementPlan(tileImprovementPlan); tileImprovementPlan.dispose(); lb.add(", land claim failed at ", tile); - if ((newTarget = findMissionTarget(aiUnit, 10, false)) == null) { + newTarget = findMissionTarget(aiUnit, 10, false); + if (newTarget == null) { return lbFail(lb, false, "no alternate target"); } setTarget(newTarget); diff --git a/src/net/sf/freecol/server/ai/mission/PrivateerMission.java b/src/net/sf/freecol/server/ai/mission/PrivateerMission.java index f1106db74f..4fea77e65f 100644 --- a/src/net/sf/freecol/server/ai/mission/PrivateerMission.java +++ b/src/net/sf/freecol/server/ai/mission/PrivateerMission.java @@ -164,8 +164,9 @@ public static int scorePath(AIUnit aiUnit, PathNode path) { * @param deferOK Enable colony fallback (not implemented). * @return A suitable {@code GoalDecider}. */ + @SuppressWarnings("PMD.UnusedFormalParameter") private static GoalDecider getGoalDecider(final AIUnit aiUnit, - @SuppressWarnings("unused") boolean deferOK) { + boolean deferOK) { return new GoalDecider() { private PathNode bestPath = null; private int bestValue = Integer.MIN_VALUE; @@ -177,12 +178,10 @@ private static GoalDecider getGoalDecider(final AIUnit aiUnit, @Override public boolean check(Unit u, PathNode path) { int value = scorePath(aiUnit, path); - if (bestValue < value) { - bestValue = value; - bestPath = path; - return true; - } - return false; + if (bestValue >= value) return false; + bestValue = value; + bestPath = path; + return true; } }; } diff --git a/src/net/sf/freecol/server/ai/mission/TransportMission.java b/src/net/sf/freecol/server/ai/mission/TransportMission.java index 768876c5b6..dff6e15f0b 100644 --- a/src/net/sf/freecol/server/ai/mission/TransportMission.java +++ b/src/net/sf/freecol/server/ai/mission/TransportMission.java @@ -59,6 +59,7 @@ import net.sf.freecol.server.ai.Cargo; import net.sf.freecol.server.ai.EuropeanAIPlayer; import net.sf.freecol.server.ai.TransportableAIObject; +import java.util.logging.Level; /** @@ -129,7 +130,7 @@ public TransportMission(AIMain aiMain, AIUnit aiUnit, */ @Override public void dispose() { - logger.finest(tag + " disposing (" + clearCargoes() + "): " + this); + if (logger.isLoggable(Level.FINEST)) logger.finest(tag + " disposing (" + clearCargoes() + "): " + this); super.dispose(); } @@ -272,7 +273,7 @@ private Cargo tFirst() { private boolean tAdd(Cargo cargo, int index) { if (!cargo.isValid()) return false; if (tFind(cargo.getTransportable()) != null) return true; - boolean change = false; + boolean change; synchronized (cargoes) { change = cargoes.isEmpty() || index == 0; if (index >= 0) { @@ -444,13 +445,15 @@ private List wrapCargoes() { * @return The unwrapped list of cargoes. */ private List unwrapCargoes(List ts) { - for (int i = 0; i < ts.size(); i++) { + int i = 0; + while (i < ts.size()) { Cargo t = ts.get(i); if (t.hasWrapped()) { List tl = t.unwrap(); ts.addAll(i+1, tl); i += tl.size(); } + i++; } return ts; } @@ -722,32 +725,42 @@ private void checkCargoes(LogBuilder lb) { dump = false; TransportableAIObject t = cargo.getTransportable(); reason = invalidMissionReason(aiCarrier, cargo.getCarrierTarget()); - if (reason != null || (reason = cargo.check(aiCarrier)) != null) { + if (reason != null) { // Just remove, it is invalid removeCargo(cargo); lb.add(", INVALID(", reason, ") ", cargo.toShortString()); - } else if (cargo.isDelivered()) { - removeCargo(cargo); - lb.add(", COMPLETED ", cargo.toShortString()); - } else if (!cargo.hasPath() && !cargo.retry()) { - reason = " no-path"; - dump = true; - } else if (carrier.hasTile() && (reason = cargo.update()) != null) { - if (reason.startsWith("invalid")) { + } else { + reason = cargo.check(aiCarrier); + if (reason != null) { + // Just remove, it is invalid removeCargo(cargo); - lb.add(", FAIL(", reason, ") ", cargo.toShortString()); - } else if (cargo.retry()) { - lb.add(", retry-", cargo.getTries(), "(", reason, ")"); - } else { + lb.add(", INVALID(", reason, ") ", cargo.toShortString()); + } else if (cargo.isDelivered()) { + removeCargo(cargo); + lb.add(", COMPLETED ", cargo.toShortString()); + } else if (!cargo.hasPath() && !cargo.retry()) { + reason = " no-path"; dump = true; + } else if (carrier.hasTile()) { + reason = cargo.update(); + if (reason != null) { + if (reason.startsWith("invalid")) { + removeCargo(cargo); + lb.add(", FAIL(", reason, ") ", cargo.toShortString()); + } else if (cargo.retry()) { + lb.add(", retry-", cargo.getTries(), "(", reason, ")"); + } else { + dump = true; + } + } + } else if (cargo.isCollectable()) { + lb.add(", collect ", cargo.toShortString()); + } else if (cargo.isDeliverable()) { + lb.add(", deliver ", cargo.toShortString()); + } else { + lb.add(", ok ", cargo.toShortString()); // Good + cargo.resetTries(); } - } else if (cargo.isCollectable()) { - lb.add(", collect ", cargo.toShortString()); - } else if (cargo.isDeliverable()) { - lb.add(", deliver ", cargo.toShortString()); - } else { - lb.add(", ok ", cargo.toShortString()); // Good - cargo.resetTries(); } if (dump) { if (cargo.isCarried()) { @@ -840,7 +853,7 @@ private CargoResult tryCargo(Cargo cargo, LogBuilder lb) { final TransportableAIObject t = cargo.getTransportable(); final Locatable l = t.getTransportLocatable(); if (l == null) { - logger.warning("Null-locatable: " + cargo); + if (logger.isLoggable(Level.WARNING)) logger.warning("Null-locatable: " + cargo); return CargoResult.TDONE; } if (!Map.isSameLocation(here, cargo.getCarrierTarget())) { @@ -856,8 +869,9 @@ private CargoResult tryCargo(Cargo cargo, LogBuilder lb) { lb.add(", ", t, " out of moves"); return CargoResult.TCONTINUE; } - if ((d = cargo.getJoinDirection()) == null) { - logger.warning("Null pickup direction" + d = cargo.getJoinDirection(); + if (d == null) { + if (logger.isLoggable(Level.WARNING)) logger.warning("Null pickup direction" + " for " + cargo.toShortString() + " at " + t.getLocation() + " to " + carrier); @@ -913,7 +927,8 @@ private CargoResult tryCargo(Cargo cargo, LogBuilder lb) { lb.add(", ", t, " about to leave"); return CargoResult.TCONTINUE; } - if ((d = cargo.getLeaveDirection()) == null) { + d = cargo.getLeaveDirection(); + if (d == null) { Unit.MoveType mt = ((AIUnit)t).getUnit() .getSimpleMoveType(t.getLocation().getTile(), cargo.getTransportTarget().getTile()); @@ -923,7 +938,7 @@ private CargoResult tryCargo(Cargo cargo, LogBuilder lb) { default: PathNode path = t.getDeliveryPath(carrier, cargo.getTransportTarget()); - logger.warning("Null direction" + if (logger.isLoggable(Level.WARNING)) logger.warning("Null direction" + " for " + cargo.toShortString() + " at " + t.getLocation().toShortString() + "/" + carrier.getLocation().toShortString() @@ -956,11 +971,12 @@ private CargoResult tryCargo(Cargo cargo, LogBuilder lb) { // Check for goods completing a wish Colony colony; AIColony aiColony; - if ((colony = (t.getLocation() == null) ? null - : t.getLocation().getColony()) != null - && (aiColony = getAIMain().getAIColony(colony)) != null - && aiColony.completeWish(t, lb)) { - aiColony.requestRearrange(); + colony = (t.getLocation() == null) ? null : t.getLocation().getColony(); + if (colony != null) { + aiColony = getAIMain().getAIColony(colony); + if (aiColony != null && aiColony.completeWish(t, lb)) { + aiColony.requestRearrange(); + } } return CargoResult.TDONE; } @@ -1503,8 +1519,9 @@ public Mission doMission(LogBuilder lb) { Mission m = euaip.getPrivateerMission(aiCarrier, null); if (m != null) return lbDone(lb, false, "going pirate"); } - if ((reason = invalidReason()) != null) { - logger.warning(tag + " post-stop failure(" + reason + reason = invalidReason(); + if (reason != null) { + if (logger.isLoggable(Level.WARNING)) logger.warning(tag + " post-stop failure(" + reason + "): " + this.toFullString()); return lbFail(lb, false, reason); } diff --git a/src/net/sf/freecol/server/ai/mission/UnitSeekAndDestroyMission.java b/src/net/sf/freecol/server/ai/mission/UnitSeekAndDestroyMission.java index 26bce29fb9..1ce80178d0 100644 --- a/src/net/sf/freecol/server/ai/mission/UnitSeekAndDestroyMission.java +++ b/src/net/sf/freecol/server/ai/mission/UnitSeekAndDestroyMission.java @@ -45,6 +45,7 @@ import net.sf.freecol.server.ai.AIUnit; import net.sf.freecol.server.ai.EuropeanAIPlayer; import net.sf.freecol.server.ai.MissionAIPlayer; +import java.util.logging.Level; /** @@ -241,12 +242,10 @@ private static GoalDecider getGoalDecider(final AIUnit aiUnit, boolean onlySettl @Override public boolean check(Unit u, PathNode path) { int value = scorePath(aiUnit, path, onlySettlements, noNativeSettlements); - if (bestValue < value) { - bestValue = value; - bestPath = path; - return true; - } - return false; + if (bestValue >= value) return false; + bestValue = value; + bestPath = path; + return true; } }; } @@ -423,7 +422,7 @@ public void setTarget(Location target) { if (settlement.isConnectedPort()) { transportTarget = settlement.getTile() .getBestDisembarkTile(unit.getOwner()); - logger.finest(tag + " chose dropoff " + transportTarget + if (logger.isLoggable(Level.FINEST)) logger.finest(tag + " chose dropoff " + transportTarget + " for attack on " + ((settlement.canBombardEnemyShip()) ? "hazardous" : "normal") @@ -530,7 +529,7 @@ && getAIPlayer().getDefendSettlementMission(aiUnit, colony) != null) { } Direction d = unitTile.getDirection(currentTarget.getTile()); if (d == null) { - logger.warning("SDDM bogus " + mt + " with " + unit + if (logger.isLoggable(Level.WARNING)) logger.warning("SDDM bogus " + mt + " with " + unit + " from " + unitTile + " to " + currentTarget + " at " + currentTarget.getTile()); return lbWait(lb); diff --git a/src/net/sf/freecol/server/ai/mission/UnitWanderHostileMission.java b/src/net/sf/freecol/server/ai/mission/UnitWanderHostileMission.java index 5d0b3b9916..f6aded1e41 100644 --- a/src/net/sf/freecol/server/ai/mission/UnitWanderHostileMission.java +++ b/src/net/sf/freecol/server/ai/mission/UnitWanderHostileMission.java @@ -181,7 +181,8 @@ public Mission doMission(LogBuilder lb) { check = checkTurns; } else check--; - if ((d = moveRandomly(tag, d)) == null) break; + d = moveRandomly(tag, d); + if (d == null) break; } return lbAt(lb); } diff --git a/src/net/sf/freecol/server/ai/package-info.java b/src/net/sf/freecol/server/ai/package-info.java index ddceb85085..e97b24e353 100644 --- a/src/net/sf/freecol/server/ai/package-info.java +++ b/src/net/sf/freecol/server/ai/package-info.java @@ -1,5 +1,5 @@ /** - *

FreeCol Artifical Intelligence

+ *

FreeCol Artifical Intelligence

* *

The main package of the Artifical Intelligence (AI) package tree.

* diff --git a/src/net/sf/freecol/server/control/InGameController.java b/src/net/sf/freecol/server/control/InGameController.java index 76914a4c7a..6cbc9ae854 100644 --- a/src/net/sf/freecol/server/control/InGameController.java +++ b/src/net/sf/freecol/server/control/InGameController.java @@ -382,7 +382,7 @@ public ServerPlayer createREFPlayer(ServerPlayer serverPlayer) { random);//-vis: safe!map if (!leftOver.isEmpty()) { // Should not happen, make this return null one day - logger.warning("Failed to board REF units: " + if (logger.isLoggable(Level.WARNING)) logger.warning("Failed to board REF units: " + join(" ", transform(leftOver, alwaysTrue(), FreeColObject::getId))); } @@ -417,7 +417,7 @@ private void csBuy(ServerUnit unit, Goods goods, int price, cs.add(See.only(owner), tile); cs.addPartial(See.only(owner), owner, "gold", String.valueOf(owner.getGold())); - logger.finest(owner.getSuffix() + " " + unit + " buys " + goods + if (logger.isLoggable(Level.FINEST)) logger.finest(owner.getSuffix() + " " + unit + " buys " + goods + " at " + sis.getName() + " for " + price); } @@ -451,7 +451,7 @@ private void csSell(ServerUnit unit, Goods goods, int price, "gold", String.valueOf(owner.getGold())); cs.addSale(owner, sis, goods.getType(), Math.round((float)price/goods.getAmount())); - logger.finest(owner.getSuffix() + " " + unit + " sells " + goods + if (logger.isLoggable(Level.FINEST)) logger.finest(owner.getSuffix() + " " + unit + " sells " + goods + " at " + sis.getName() + " for " + price); } @@ -479,7 +479,7 @@ private void csGift(ServerUnit unit, Goods goods, int price, final Tile tile = sis.getTile(); tile.updateIndianSettlement(owner); cs.add(See.only(owner), tile); - logger.finest(owner.getSuffix() + " " + unit + " gives " + goods + if (logger.isLoggable(Level.FINEST)) logger.finest(owner.getSuffix() + " " + unit + " gives " + goods + " at " + sis.getName() + " worth " + price); } @@ -736,7 +736,7 @@ private void csMonarchAction(final ServerPlayer serverPlayer, cs.addPartial(See.only(serverPlayer), serverPlayer, "gold", String.valueOf(serverPlayer.getGold()), "score", String.valueOf(serverPlayer.getScore())); - logger.fine("War support v " + enemy.getNation().getSuffix() + if (logger.isLoggable(Level.FINE)) logger.fine("War support v " + enemy.getNation().getSuffix() + " " + warGold + " gold + " + Messages.message(AbstractUnit .getListLabel(", ", warSupport))); } @@ -786,7 +786,7 @@ private void csMonarchAction(final ServerPlayer serverPlayer, random, cs); break; case DISPLEASURE: default: - logger.warning("Bogus action: " + action); + if (logger.isLoggable(Level.WARNING)) logger.warning("Bogus action: " + action); break; } } @@ -932,6 +932,7 @@ public ChangeSet assignTradeRoute(ServerPlayer serverPlayer, Unit unit, */ public ChangeSet buildSettlement(ServerPlayer serverPlayer, Unit unit, String name) { + String settlementName = name; final ServerGame game = getGame(); final Specification spec = game.getSpecification(); ChangeSet cs = new ChangeSet(); @@ -939,12 +940,12 @@ public ChangeSet buildSettlement(ServerPlayer serverPlayer, Unit unit, // Build settlement Tile tile = unit.getTile(); Settlement settlement; - if (Player.ASSIGN_SETTLEMENT_NAME.equals(name)) { - name = serverPlayer.getSettlementName(random); + if (Player.ASSIGN_SETTLEMENT_NAME.equals(settlementName)) { + settlementName = serverPlayer.getSettlementName(random); } if (serverPlayer.isEuropean()) { StringTemplate nation = serverPlayer.getNationLabel(); - settlement = new ServerColony(game, serverPlayer, name, tile); + settlement = new ServerColony(game, serverPlayer, settlementName, tile); for (Tile t : tile.getSurroundingTiles(settlement.getRadius())) { t.cacheUnseen();//+til } @@ -1053,7 +1054,7 @@ private ChangeSet buyGoods(ServerPlayer serverPlayer, GoodsType type, cs.addPartial(See.only(serverPlayer), serverPlayer, "gold", String.valueOf(serverPlayer.getGold())); cs.add(See.only(serverPlayer), carrier); - logger.finest(carrier + " bought " + amount + "(" + buyAmount + ")" + if (logger.isLoggable(Level.FINEST)) logger.finest(carrier + " bought " + amount + "(" + buyAmount + ")" + " " + type.getSuffix() + " in Europe for " + (serverPlayer.getGold() - gold)); // Action occurs in Europe, nothing is visible to other players. @@ -1352,7 +1353,7 @@ public ChangeSet continuePlaying(ServerPlayer serverPlayer) { if (!getFreeColServer().getSinglePlayer()) { logger.warning("Can not continue playing in multiplayer!"); } else if (serverPlayer != game.checkForWinner()) { - logger.warning("Can not continue playing, as " + if (logger.isLoggable(Level.WARNING)) logger.warning("Can not continue playing, as " + serverPlayer.getName() + " has not won the game!"); } else { @@ -1360,7 +1361,7 @@ public ChangeSet continuePlaying(ServerPlayer serverPlayer) { spec.setBoolean(GameOptions.VICTORY_DEFEAT_REF, false); spec.setBoolean(GameOptions.VICTORY_DEFEAT_EUROPEANS, false); spec.setBoolean(GameOptions.VICTORY_DEFEAT_HUMANS, false); - logger.info("Disabled victory conditions, as " + if (logger.isLoggable(Level.INFO)) logger.info("Disabled victory conditions, as " + serverPlayer.getName() + " has won, but is continuing to play."); } @@ -1491,7 +1492,7 @@ public ChangeSet declareIndependence(final ServerPlayer serverPlayer, Function.identity(), comp); if (!natives.isEmpty()) { Player good = first(natives); - logger.info("Native ally following independence: " + good); + if (logger.isLoggable(Level.INFO)) logger.info("Native ally following independence: " + good); cs.addMessage(serverPlayer, new ModelMessage(MessageType.FOREIGN_DIPLOMACY, "declareIndependence.nativeSupport", good) @@ -1499,7 +1500,8 @@ public ChangeSet declareIndependence(final ServerPlayer serverPlayer, .add("%ruler%", serverPlayer.getRulerNameKey())); int delta; switch (good.getStance(serverPlayer)) { - case ALLIANCE: case PEACE: default: + case ALLIANCE: + case PEACE: delta = 0; break; case CEASE_FIRE: @@ -1510,6 +1512,8 @@ public ChangeSet declareIndependence(final ServerPlayer serverPlayer, delta = Tension.Level.CONTENT.getLimit() - good.getTension(serverPlayer).getValue(); break; + default: + delta = 0; } ((ServerPlayer)good).csModifyTension(serverPlayer, delta, cs); Player.makeContact(good, refPlayer); @@ -1524,7 +1528,7 @@ public ChangeSet declareIndependence(final ServerPlayer serverPlayer, bad = p; if (!p.atWarWith(serverPlayer)) break; } - logger.info("Native enemy following independence: " + bad); + if (logger.isLoggable(Level.INFO)) logger.info("Native enemy following independence: " + bad); if (bad != null) { switch (bad.getStance(serverPlayer)) { case PEACE: case CEASE_FIRE: @@ -1554,7 +1558,7 @@ public ChangeSet declareIndependence(final ServerPlayer serverPlayer, if (mercPrice > 0) { serverPlayer.csMercenaries(mercPrice, mercs, Monarch.MonarchAction.HESSIAN_MERCENARIES, random, cs); - logger.info("Mercenary force offer on declaration (" + if (logger.isLoggable(Level.INFO)) logger.info("Mercenary force offer on declaration (" + Messages.message(AbstractUnit.getListLabel(", ", mercs)) + ") for " + mercPrice); } else { @@ -1689,7 +1693,7 @@ public ChangeSet deliverGiftToSettlement(ServerPlayer serverPlayer, cs.add(See.only(receiver), settlement); cs.addMessage(receiver, m); } - logger.info("Gift delivered by unit: " + unit.getId() + if (logger.isLoggable(Level.INFO)) logger.info("Gift delivered by unit: " + unit.getId() + " to settlement: " + settlement.getName()); // Others can see unit capacity, receiver gets it own items. @@ -1857,9 +1861,9 @@ public ChangeSet diplomacy(ServerPlayer serverPlayer, Unit ourUnit, } session = new DiplomacySession(ourUnit, otherColony, getTimeout()); session.register(); - logger.info("New diplomacy session: " + session); + if (logger.isLoggable(Level.INFO)) logger.info("New diplomacy session: " + session); } else { - logger.info("Continuing diplomacy session: " + session + if (logger.isLoggable(Level.INFO)) logger.info("Continuing diplomacy session: " + session + " from " + ourUnit); } serverPlayer.csDiplomacy(session, agreement, cs); @@ -1887,7 +1891,7 @@ public ChangeSet diplomacy(ServerPlayer serverPlayer, Colony ourColony, + otherUnit.getId() + "/" + ourColony.getId() + " with " + agreement); } else { - logger.info("Continuing diplomacy session: " + session + if (logger.isLoggable(Level.INFO)) logger.info("Continuing diplomacy session: " + session + " from " + ourColony); } serverPlayer.csDiplomacy(session, agreement, cs); @@ -2059,7 +2063,7 @@ public ChangeSet endTurn(ServerPlayer serverPlayer) { for (;;) { current.csEndTurn(cs); - logger.finest("Ending turn for " + current.getName()); + if (logger.isLoggable(Level.FINEST)) logger.finest("Ending turn for " + current.getName()); current.clearModelMessages(); // Check for new turn @@ -2083,7 +2087,8 @@ public ChangeSet endTurn(ServerPlayer serverPlayer) { cs.clear(); } - if ((current = (ServerPlayer)serverGame.getNextPlayer()) == null) { + current = (ServerPlayer)serverGame.getNextPlayer(); + if (current == null) { // "can not happen" return serverPlayer.clientError("Can not get next player"); } @@ -2097,7 +2102,7 @@ public ChangeSet endTurn(ServerPlayer serverPlayer) { // Fall through case IS_DEAD: current.csWithdraw(cs, null, null); - logger.info("For " + serverPlayer.getSuffix() + if (logger.isLoggable(Level.INFO)) logger.info("For " + serverPlayer.getSuffix() + ", " + current.getNation() + " has withdrawn."); break; case IS_AUTORECRUIT: @@ -2123,7 +2128,7 @@ public ChangeSet endTurn(ServerPlayer serverPlayer) { final Comparator scoreComp = Comparator.comparingInt(Player::getScore).reversed(); winner = (ServerPlayer)first(sort(connected, scoreComp)); - logger.info("No human player left, winner is: " + winner); + if (logger.isLoggable(Level.INFO)) logger.info("No human player left, winner is: " + winner); if (debugOnlyAITurns > 0) { // Complete debug runs FreeColDebugger.signalEndDebugRun(); } @@ -2173,7 +2178,7 @@ public ChangeSet endTurn(ServerPlayer serverPlayer) { action = debugMonarchAction; debugMonarchAction = null; debugMonarchPlayer = null; - logger.finest("Debug monarch action: " + action); + if (logger.isLoggable(Level.FINEST)) logger.finest("Debug monarch action: " + action); } else if (monarch != null) { action = RandomChoice.getWeightedRandom(logger, "Choose monarch action", @@ -2181,10 +2186,10 @@ public ChangeSet endTurn(ServerPlayer serverPlayer) { } if (action != null) { if (monarch.actionIsValid(action)) { - logger.finest("Monarch action: " + action); + if (logger.isLoggable(Level.FINEST)) logger.finest("Monarch action: " + action); csMonarchAction(current, action, cs); } else { - logger.finest("Skipping invalid monarch action: " + if (logger.isLoggable(Level.FINEST)) logger.finest("Skipping invalid monarch action: " + action); } } @@ -2295,7 +2300,7 @@ public ChangeSet enterRevengeMode(ServerPlayer serverPlayer) { public ChangeSet equipForRole(ServerPlayer serverPlayer, Unit unit, Role role, int roleCount) { ChangeSet cs = new ChangeSet(); - boolean ret = false; + boolean ret; if (unit.isInEurope()) { ServerEurope serverEurope = (ServerEurope)serverPlayer.getEurope(); ret = serverEurope.csEquipForRole(unit, role, roleCount, @@ -2362,6 +2367,8 @@ public ChangeSet establishMission(ServerPlayer serverPlayer, sis.csChangeMissionary(sUnit, cs);//+vis(serverPlayer) break; + default: + break; } // Add the descriptive message. @@ -2396,7 +2403,7 @@ public ChangeSet europeanFirstContact(ServerPlayer serverPlayer, DiplomaticTrade agreement) { String err = "Missing contact diplomacy session for "; DiplomacySession ds; - boolean compatible = false; + boolean compatible; if (ourColony != null) { ds = DiplomacySession.findContactSession(otherUnit, ourColony); if (ds == null) return serverPlayer.clientError(err @@ -2413,7 +2420,7 @@ public ChangeSet europeanFirstContact(ServerPlayer serverPlayer, + ourUnit.getId() + " and " + otherColony.getId()); compatible = ds.isCompatible(ourUnit, otherColony); } - logger.info("Continuing " + ((compatible) ? "" : "in") + if (logger.isLoggable(Level.INFO)) logger.info("Continuing " + ((compatible) ? "" : "in") + "compatible contact session: " + ds.getKey()); ChangeSet cs = new ChangeSet(); @@ -2548,7 +2555,7 @@ public ChangeSet indianDemand(final ServerPlayer serverPlayer, Unit unit, session = new NativeDemandSession(unit, colony, type, amount, getTimeout()); session.register(); - logger.info("Native demand(begin) " + session.getKey() + ": " + if (logger.isLoggable(Level.INFO)) logger.info("Native demand(begin) " + session.getKey() + ": " + serverPlayer.getName() + " unit " + unit + " demands " + amount + " " + ((type == null) ? "gold" : type) + " from " + colony.getName()); @@ -2559,7 +2566,7 @@ public ChangeSet indianDemand(final ServerPlayer serverPlayer, Unit unit, return serverPlayer.clientError("Replying to missing demand: " + unit.getId() + "," + colony.getId()); } - logger.info("Native demand(" + result + ") " + session.getKey() + if (logger.isLoggable(Level.INFO)) logger.info("Native demand(" + result + ") " + session.getKey() + ": " + serverPlayer.getName() + " unit " + unit + " demands " + amount + " " + ((type == null) ? "gold" : type) + " from " + colony.getName()); @@ -2706,7 +2713,7 @@ public ChangeSet loadGoods(ServerPlayer serverPlayer, Location loc, ChangeSet cs = new ChangeSet(); GoodsLocation.moveGoods(gl, goodsType, amount, carrier); - logger.finest(Messages.message(loc.getLocationLabel()) + if (logger.isLoggable(Level.FINEST)) logger.finest(Messages.message(loc.getLocationLabel()) + " loaded " + amount + " " + goodsType.getSuffix() + " onto " + carrier); cs.add(See.only(serverPlayer), gl.getGoodsContainer()); @@ -3034,7 +3041,7 @@ public ChangeSet nativeGift(ServerPlayer serverPlayer, .addName("%settlement%", colony.getName()); cs.addMessage(otherPlayer, m); cs.add(See.only(otherPlayer), colony); - logger.info("Gift delivered by unit: " + unit.getId() + if (logger.isLoggable(Level.INFO)) logger.info("Gift delivered by unit: " + unit.getId() + " to colony " + colony.getName() + ": " + goods); // Others might see unit capacity? @@ -3054,8 +3061,9 @@ public ChangeSet nativeGift(ServerPlayer serverPlayer, @SuppressFBWarnings(value="SF_SWITCH_FALLTHROUGH") public ChangeSet nativeTrade(ServerPlayer serverPlayer, NativeTradeAction action, NativeTrade nt) { - final ServerUnit unit = (ServerUnit)nt.getUnit(); - final IndianSettlement is = nt.getIndianSettlement(); + NativeTrade currentTrade = nt; + final ServerUnit unit = (ServerUnit)currentTrade.getUnit(); + final IndianSettlement is = currentTrade.getIndianSettlement(); final Player otherPlayer = (serverPlayer.owns(unit)) ? is.getOwner() : unit.getOwner(); @@ -3070,9 +3078,9 @@ public ChangeSet nativeTrade(ServerPlayer serverPlayer, + " player expected for " + action + ": " + serverPlayer.getSuffix()); } else if (action == NativeTradeAction.OPEN && session != null) { - return serverPlayer.clientError("Session already open for: " + nt); + return serverPlayer.clientError("Session already open for: " + currentTrade); } else if (action != NativeTradeAction.OPEN && session == null) { - return serverPlayer.clientError("No session found for: " + nt); + return serverPlayer.clientError("No session found for: " + currentTrade); } ChangeSet cs = new ChangeSet(); @@ -3084,9 +3092,9 @@ public ChangeSet nativeTrade(ServerPlayer serverPlayer, + " has no moves left."); } // Register a session and ask the natives to price the goods. - nt = NativeTradeSession.openSession(nt); + currentTrade = NativeTradeSession.openSession(currentTrade); cs.add(See.only(otherPlayer), - new NativeTradeMessage(action, nt)); + new NativeTradeMessage(action, currentTrade)); break; case CLOSE: // Just close the session @@ -3094,63 +3102,63 @@ public ChangeSet nativeTrade(ServerPlayer serverPlayer, break; case BUY: // Check goods (not whole item, price might be wrong), forward - item = nt.getItem(); - nt.mergeFrom(session.getNativeTrade()); + item = currentTrade.getItem(); + currentTrade.mergeFrom(session.getNativeTrade()); if (item == null) { - return serverPlayer.clientError("Null purchase: " + nt); - } else if (!nt.canBuy()) { - return serverPlayer.clientError("Can not buy: " + nt); - } else if (find(nt.getSettlementToUnit(), + return serverPlayer.clientError("Null purchase: " + currentTrade); + } else if (!currentTrade.canBuy()) { + return serverPlayer.clientError("Can not buy: " + currentTrade); + } else if (find(currentTrade.getSettlementToUnit(), item.goodsMatcher()) == null) { return serverPlayer.clientError("Item missing for " - + action + ": " + nt); + + action + ": " + currentTrade); } else if (!serverPlayer.checkGold(item.getPrice())) { return serverPlayer.clientError("Player can not afford item: " - + nt); + + currentTrade); } - nt.setItem(item); + currentTrade.setItem(item); cs.add(See.only(otherPlayer), - new NativeTradeMessage(action, nt)); + new NativeTradeMessage(action, currentTrade)); break; case SELL: // Check goods, forward - item = nt.getItem(); - nt.mergeFrom(session.getNativeTrade()); + item = currentTrade.getItem(); + currentTrade.mergeFrom(session.getNativeTrade()); if (item == null) { - return serverPlayer.clientError("Null sale: " + nt); - } else if (item.priceIsSet() && !nt.canSell()) { - return serverPlayer.clientError("Can not sell: " + nt); - } else if (find(nt.getUnitToSettlement(), + return serverPlayer.clientError("Null sale: " + currentTrade); + } else if (item.priceIsSet() && !currentTrade.canSell()) { + return serverPlayer.clientError("Can not sell: " + currentTrade); + } else if (find(currentTrade.getUnitToSettlement(), item.goodsMatcher()) == null) { return serverPlayer.clientError("Item missing for " - + action + ": " + nt); + + action + ": " + currentTrade); } - nt.setItem(item); + currentTrade.setItem(item); cs.add(See.only(otherPlayer), - new NativeTradeMessage(action, nt)); + new NativeTradeMessage(action, currentTrade)); break; case GIFT: // Check goods, forward - item = nt.getItem(); - nt.mergeFrom(session.getNativeTrade()); + item = currentTrade.getItem(); + currentTrade.mergeFrom(session.getNativeTrade()); if (item == null) { - return serverPlayer.clientError("Null gift: " + nt); - } else if (!nt.canGift()) { - return serverPlayer.clientError("Can not gift: " + nt); - } else if (find(nt.getUnitToSettlement(), + return serverPlayer.clientError("Null gift: " + currentTrade); + } else if (!currentTrade.canGift()) { + return serverPlayer.clientError("Can not gift: " + currentTrade); + } else if (find(currentTrade.getUnitToSettlement(), item.goodsMatcher()) == null) { return serverPlayer.clientError("Item missing for " - + action + ": " + nt); + + action + ": " + currentTrade); } - nt.setItem(item); + currentTrade.setItem(item); cs.add(See.only(otherPlayer), - new NativeTradeMessage(action, nt)); + new NativeTradeMessage(action, currentTrade)); break; case ACK_OPEN: // Natives are prepared to trade, inform player - session.getNativeTrade().mergeFrom(nt); + session.getNativeTrade().mergeFrom(currentTrade); cs.add(See.only(otherPlayer), - new NativeTradeMessage(action, nt)); + new NativeTradeMessage(action, currentTrade)); // Set unit moves to zero to avoid cheating. If no // action is taken, the moves will be restored when // closing the session. @@ -3161,45 +3169,45 @@ public ChangeSet nativeTrade(ServerPlayer serverPlayer, case ACK_BUY_HAGGLE: case ACK_SELL_HAGGLE: case NAK_GOODS: // Successful haggle or polite refusal of gift - session.getNativeTrade().mergeFrom(nt); + session.getNativeTrade().mergeFrom(currentTrade); cs.add(See.only(otherPlayer), - new NativeTradeMessage(action, nt)); + new NativeTradeMessage(action, currentTrade)); break; case ACK_BUY: // Buy succeeded, update goods, inform player - item = nt.getItem(); + item = currentTrade.getItem(); csBuy(unit, item.getGoods(), item.getPrice(), (ServerIndianSettlement)is, cs); - nt.setBuy(false); - nt.addToUnit(item); - session.getNativeTrade().mergeFrom(nt); + currentTrade.setBuy(false); + currentTrade.addToUnit(item); + session.getNativeTrade().mergeFrom(currentTrade); session.getNativeTrade().setBuy(false); cs.add(See.only(otherPlayer), - new NativeTradeMessage(action, nt)); + new NativeTradeMessage(action, currentTrade)); break; case ACK_SELL: // Sell succeeded, update goods, inform player - item = nt.getItem(); + item = currentTrade.getItem(); csSell(unit, item.getGoods(), item.getPrice(), (ServerIndianSettlement)is, cs); - nt.setSell(false); - nt.removeFromUnit(item); - session.getNativeTrade().mergeFrom(nt); + currentTrade.setSell(false); + currentTrade.removeFromUnit(item); + session.getNativeTrade().mergeFrom(currentTrade); session.getNativeTrade().setSell(false); cs.add(See.only(otherPlayer), - new NativeTradeMessage(action, nt)); + new NativeTradeMessage(action, currentTrade)); break; case ACK_GIFT: // Gift succeeded, update goods, inform player - item = nt.getItem(); + item = currentTrade.getItem(); csGift(unit, item.getGoods(), item.getPrice(), (ServerIndianSettlement)is, cs); - nt.setGift(false); - nt.removeFromUnit(item); - session.getNativeTrade().mergeFrom(nt); + currentTrade.setGift(false); + currentTrade.removeFromUnit(item); + session.getNativeTrade().mergeFrom(currentTrade); session.getNativeTrade().setGift(false); cs.add(See.only(otherPlayer), - new NativeTradeMessage(action, nt)); + new NativeTradeMessage(action, currentTrade)); break; case NAK_HAGGLE: case NAK_NOSALE: // Fail, close @@ -3208,16 +3216,16 @@ public ChangeSet nativeTrade(ServerPlayer serverPlayer, "movesLeft", String.valueOf(unit.getMovesLeft())); // Fall through case NAK_INVALID: case NAK_HOSTILE: - session.getNativeTrade().mergeFrom(nt); + session.getNativeTrade().mergeFrom(currentTrade); cs.add(See.only(otherPlayer), - new NativeTradeMessage(action, nt)); + new NativeTradeMessage(action, currentTrade)); session.complete(cs); break; default: return serverPlayer.clientError("Bogus action: " + action); } - logger.fine("Native trade(" + downCase(action.toString()) + ": " + nt); + if (logger.isLoggable(Level.FINE)) logger.fine("Native trade(" + downCase(action.toString()) + ": " + currentTrade); // Update the other player if needed getGame().sendToOthers(serverPlayer, cs); @@ -3305,8 +3313,9 @@ public ChangeSet payForBuilding(ServerPlayer serverPlayer, Colony colony) { int amount = ag.getAmount(); if (type.isStorable()) { // FIXME: should also check canTrade(type, Access.?) - if ((amount = serverPlayer.buyInEurope(random, container, - type, amount)) < 0) { + amount = serverPlayer.buyInEurope(random, container, + type, amount); + if (amount < 0) { return serverPlayer.clientError("Can not buy " + amount + " " + type + " for " + build); } @@ -3392,7 +3401,7 @@ public ChangeSet rearrangeColony(ServerPlayer serverPlayer, Colony colony, todo.add(todo.size(), a); break; default: - logger.warning("Bad move for " + a.unit + " to " + wl); + if (logger.isLoggable(Level.WARNING)) logger.warning("Bad move for " + a.unit + " to " + wl); break; } } @@ -3609,13 +3618,13 @@ private ChangeSet sellGoods(ServerPlayer serverPlayer, GoodsType type, serverPlayer.csFlushMarket(type, cs); cs.addPartial(See.only(serverPlayer), serverPlayer, "gold", String.valueOf(serverPlayer.getGold())); - logger.finest(carrier + " sold " + amount + "(" + sellAmount + ")" + if (logger.isLoggable(Level.FINEST)) logger.finest(carrier + " sold " + amount + "(" + sellAmount + ")" + " " + type.getSuffix() + " in Europe for " + (serverPlayer.getGold() - gold)); } else { // Dumping goods in Europe GoodsLocation.moveGoods(carrier, type, amount, null); - logger.finest(carrier + " dumped " + amount + if (logger.isLoggable(Level.FINEST)) logger.finest(carrier + " dumped " + amount + " " + type.getSuffix() + " in Europe"); } carrier.setMovesLeft(0); @@ -3689,14 +3698,15 @@ public ChangeSet setCurrentStop(ServerPlayer serverPlayer, Unit unit, */ public ChangeSet setDestination(ServerPlayer serverPlayer, Unit unit, Location destination) { + Location targetDestination = destination; if (unit.getTradeRoute() != null) { // Override destination to bring the unit to port. - if (destination == null && unit.isAtSea()) { - destination = unit.getStop().getLocation(); + if (targetDestination == null && unit.isAtSea()) { + targetDestination = unit.getStop().getLocation(); } unit.setTradeRoute(null); } - unit.setDestination(destination); + unit.setDestination(targetDestination); // Others can not see a destination change. return new ChangeSet().add(See.only(serverPlayer), unit); @@ -3787,7 +3797,7 @@ public ChangeSet spySettlement(ServerPlayer serverPlayer, Unit unit, Settlement settlement) { ChangeSet cs = new ChangeSet(); - logger.info("Spy settlement for " + unit.getId() + if (logger.isLoggable(Level.INFO)) logger.info("Spy settlement for " + unit.getId() + " at " + settlement.getId() + "(" + settlement.getName() + ")"); cs.addSpy(unit, settlement); unit.setMovesLeft(0); @@ -3864,7 +3874,7 @@ public ChangeSet unloadGoods(ServerPlayer serverPlayer, GoodsType goodsType, Settlement settlement = carrier.getSettlement(); if (settlement != null) { GoodsLocation.moveGoods(carrier, goodsType, amount, settlement); - logger.finest(carrier + if (logger.isLoggable(Level.FINEST)) logger.finest(carrier + " unloaded " + amount + " " + goodsType.getSuffix() + " to " + settlement.getName()); cs.add(See.only(serverPlayer), settlement.getGoodsContainer()); @@ -3876,7 +3886,7 @@ public ChangeSet unloadGoods(ServerPlayer serverPlayer, GoodsType goodsType, } } else { // Dump of goods onto a tile GoodsLocation.moveGoods(carrier, goodsType, amount, null); - logger.finest(carrier + " dumped " + amount + if (logger.isLoggable(Level.FINEST)) logger.finest(carrier + " dumped " + amount + " " + goodsType.getSuffix() + " to " + carrier.getLocation()); cs.add(See.perhaps(), (FreeColGameObject)carrier.getLocation()); // Others might see a capacity change. @@ -3902,10 +3912,13 @@ public ChangeSet updateTradeRoute(ServerPlayer serverPlayer, if (tradeRoute == null || tradeRoute.getId() == null || tradeRoute.getName() == null) { return serverPlayer.clientError("Bogus route"); - } else if ((fail = tradeRoute.verify()) != null) { + } + fail = tradeRoute.verify(); + if (fail != null) { return serverPlayer.clientError(Messages.message(fail)); - } else if ((tr = game.getFreeColGameObject(tradeRoute.getId(), - TradeRoute.class)) == null) { + } + tr = game.getFreeColGameObject(tradeRoute.getId(), TradeRoute.class); + if (tr == null) { return serverPlayer.clientError("Not an existing trade route: " + tradeRoute.getId()); } diff --git a/src/net/sf/freecol/server/control/PreGameController.java b/src/net/sf/freecol/server/control/PreGameController.java index e469746211..9e6ce2250d 100644 --- a/src/net/sf/freecol/server/control/PreGameController.java +++ b/src/net/sf/freecol/server/control/PreGameController.java @@ -107,7 +107,7 @@ public ChangeSet ready(ServerPlayer serverPlayer, boolean ready) { * @return A {@code ChangeSet} encapsulating this action. */ public ChangeSet requestLaunch(ServerPlayer serverPlayer) { - logger.info("Launching for " + serverPlayer); + if (logger.isLoggable(Level.INFO)) logger.info("Launching for " + serverPlayer); if (setLaunching(true)) { logger.warning("Already launching"); return null; diff --git a/src/net/sf/freecol/server/generator/ColonizationMapLoader.java b/src/net/sf/freecol/server/generator/ColonizationMapLoader.java index 6ab012f870..fc8350d242 100644 --- a/src/net/sf/freecol/server/generator/ColonizationMapLoader.java +++ b/src/net/sf/freecol/server/generator/ColonizationMapLoader.java @@ -132,12 +132,12 @@ public ColonizationMapLoader(File file) throws IOException { layer1 = new byte[size]; reader.readFully(layer1); } catch (EOFException ee) { - logger.log(Level.SEVERE, "File (" + file + ") is too short.", ee); + if (logger.isLoggable(Level.SEVERE)) logger.log(Level.SEVERE, "File (" + file + ") is too short.", ee); } catch (FileNotFoundException fe) { - logger.log(Level.SEVERE, "File (" + file + ") was not found.", fe); + if (logger.isLoggable(Level.SEVERE)) logger.log(Level.SEVERE, "File (" + file + ") was not found.", fe); } catch (IOException e) { - logger.log(Level.SEVERE, "File (" + file + ") is corrupt and cannot be read.", e); + if (logger.isLoggable(Level.SEVERE)) logger.log(Level.SEVERE, "File (" + file + ") is corrupt and cannot be read.", e); } } @@ -159,10 +159,6 @@ public Layer loadMap(Game game, Layer layer) { // import only the land / water distinction for (int y = 0; y < header[HEIGHT]; y++) { for (int x = 0; x < header[WIDTH]; x++) { - int decimal = layer1[index] & 0xff; - int terrain = decimal & 0b11111; - tileType = (terrain == OCEAN || terrain == HIGH_SEAS) ? - TileType.WATER : TileType.LAND; index++; } } diff --git a/src/net/sf/freecol/server/generator/EuropeanStartingPositionsGenerator.java b/src/net/sf/freecol/server/generator/EuropeanStartingPositionsGenerator.java index aadb52fe92..e86d275dcb 100644 --- a/src/net/sf/freecol/server/generator/EuropeanStartingPositionsGenerator.java +++ b/src/net/sf/freecol/server/generator/EuropeanStartingPositionsGenerator.java @@ -48,6 +48,7 @@ import net.sf.freecol.server.model.ServerColony; import net.sf.freecol.server.model.ServerPlayer; import net.sf.freecol.server.model.ServerUnit; +import java.util.logging.Level; /** * Handles the starting placement of European units. @@ -240,7 +241,7 @@ private boolean isMapDefinedStartingPositionsAvailableFor(List europeanP for (Player player : europeanPlayers) { final Area area = game.getNationStartingArea(player.getNation()); if (area == null || area.getTiles().isEmpty()) { - logger.info("No map defined starting area for: " + player.getNationId()); + if (logger.isLoggable(Level.INFO)) logger.info("No map defined starting area for: " + player.getNationId()); if (positionType == GameOptions.STARTING_POSITIONS_CLASSIC || positionType == GameOptions.STARTING_POSITIONS_HISTORICAL) { break; diff --git a/src/net/sf/freecol/server/generator/FreeColMapLoader.java b/src/net/sf/freecol/server/generator/FreeColMapLoader.java index a8d76547a7..c2a921e25b 100644 --- a/src/net/sf/freecol/server/generator/FreeColMapLoader.java +++ b/src/net/sf/freecol/server/generator/FreeColMapLoader.java @@ -47,7 +47,7 @@ */ public class FreeColMapLoader implements MapLoader { - private Map importMap = null; + private Map importMap; /** * Constructor for the FreeColMapLoader class. diff --git a/src/net/sf/freecol/server/generator/River.java b/src/net/sf/freecol/server/generator/River.java index d218fb5417..43cd9c8392 100644 --- a/src/net/sf/freecol/server/generator/River.java +++ b/src/net/sf/freecol/server/generator/River.java @@ -34,6 +34,7 @@ import net.sf.freecol.server.model.ServerRegion; import static net.sf.freecol.common.util.CollectionUtils.*; import static net.sf.freecol.common.util.RandomUtils.*; +import java.util.logging.Level; /** @@ -148,7 +149,7 @@ public River(Map map, java.util.Map riverMap, .getTileImprovementType("model.improvement.river"); this.direction = getRandomMember(logger, "River", Direction.longSides, random); - logger.fine("Starting new river flowing " + direction); + if (logger.isLoggable(Level.FINE)) logger.fine("Starting new river flowing " + direction); } public List getSections() { @@ -269,13 +270,13 @@ public boolean flowFromSource(Tile tile) { map.getSpecification().getTileImprovementType("model.improvement.river"); if (!riverType.isTileTypeAllowed(tile.getType())) { // Mountains, ocean cannot have rivers - logger.fine("Tile (" + tile + ") can not have a river."); + if (logger.isLoggable(Level.FINE)) logger.fine("Tile (" + tile + ") can not have a river."); return false; } else if (isNextToWater(tile)) { - logger.fine("Tile (" + tile + ") is next to water."); + if (logger.isLoggable(Level.FINE)) logger.fine("Tile (" + tile + ") is next to water."); return false; } else { - logger.fine("Tile (" + tile + ") is suitable source."); + if (logger.isLoggable(Level.FINE)) logger.fine("Tile (" + tile + ") is suitable source."); return flow(tile); } } @@ -296,7 +297,7 @@ private boolean flow(Tile source) { int index = randomInt(logger, "Flow", random, length); DirectionChange change = DirectionChange.values()[index]; other.direction = change.getNewDirection(other.direction); - logger.fine("Direction is now " + other.direction); + if (logger.isLoggable(Level.FINE)) logger.fine("Direction is now " + other.direction); } for (DirectionChange change : DirectionChange.values()) { @@ -307,13 +308,13 @@ private boolean flow(Tile source) { // is the tile suitable for this river? if (!other.riverType.isTileTypeAllowed(nextTile.getType())) { // Mountains, ocean cannot have rivers - logger.fine("Tile (" + nextTile + ") can not have a river."); + if (logger.isLoggable(Level.FINE)) logger.fine("Tile (" + nextTile + ") can not have a river."); continue; } else if (other.contains(nextTile)) { - logger.fine("Tile (" + nextTile + ") is already in river."); + if (logger.isLoggable(Level.FINE)) logger.fine("Tile (" + nextTile + ") is already in river."); continue; } else if (other.isNextToSelf(nextTile)) { - logger.fine("Tile (" + nextTile + ") is next to the river."); + if (logger.isLoggable(Level.FINE)) logger.fine("Tile (" + nextTile + ") is next to the river."); continue; } else { // find out if an adjacent tile is next to water @@ -329,7 +330,7 @@ private boolean flow(Tile source) { other.sections.add(lastSection); if (t.hasRiver() && t.isLand()) { - logger.fine("Tile (" + t + ") is next to another river."); + if (logger.isLoggable(Level.FINE)) logger.fine("Tile (" + t + ") is next to another river."); // increase the size of the other river other.nextRiver = other.riverMap.get(t); other.nextRiver.grow(lastSection, t); @@ -342,7 +343,7 @@ private boolean flow(Tile source) { other.drawToMap(sections); } else { // flow into the sea (or a lake) - logger.fine("Tile (" + t + ") is next to water."); + if (logger.isLoggable(Level.FINE)) logger.fine("Tile (" + t + ") is next to water."); River someRiver = other.riverMap.get(t); if (someRiver == null) { other.sections.add(new RiverSection(t, lastDir.getReverseDirection())); @@ -360,7 +361,7 @@ private boolean flow(Tile source) { return true; } // not next to water - logger.fine("Tile (" + nextTile + ") is suitable."); + if (logger.isLoggable(Level.FINE)) logger.fine("Tile (" + nextTile + ") is suitable."); other.sections.add(new RiverSection(source, dir)); source = nextTile; continue flow; @@ -423,13 +424,13 @@ private void drawToMap(List sections) { tile.changeType(greatRiver); // changing the type resets the improvements //container.addRiver(section.getSize(), section.encodeStyle()); - logger.fine("Added fjord (magnitude: " + section.getSize() + + if (logger.isLoggable(Level.FINE)) logger.fine("Added fjord (magnitude: " + section.getSize() + ") to tile: " + section.getTile()); } else if (section.getSize() > TileImprovement.NO_RIVER) { final int magnitude = Math.min(section.getSize(), TileImprovement.LARGE_RIVER); String style = section.encodeStyle(); tile.addRiver(magnitude, style); - logger.fine("Added river" + if (logger.isLoggable(Level.FINE)) logger.fine("Added river" + "(magnitude: " + section.getSize() + " style: " + style); } diff --git a/src/net/sf/freecol/server/generator/SimpleMapGenerator.java b/src/net/sf/freecol/server/generator/SimpleMapGenerator.java index e3b145e7a3..f596001ca5 100644 --- a/src/net/sf/freecol/server/generator/SimpleMapGenerator.java +++ b/src/net/sf/freecol/server/generator/SimpleMapGenerator.java @@ -76,6 +76,7 @@ import net.sf.freecol.server.model.ServerPlayer; import net.sf.freecol.server.model.ServerRegion; import net.sf.freecol.server.model.ServerUnit; +import java.util.logging.Level; /** @@ -344,7 +345,7 @@ private void makeNativeSettlements(final Map map, Map importMap, .filter(t -> settlementTiles.contains(t)) .collect(Collectors.toCollection(LinkedHashSet::new)); if (settlementTilesForNation.isEmpty()) { - logger.warning("No settlements for nationType=" + player.getNationId()); + if (logger.isLoggable(Level.WARNING)) logger.warning("No settlements for nationType=" + player.getNationId()); } designatedArea.put(player, settlementTilesForNation); } @@ -361,7 +362,7 @@ private void makeNativeSettlements(final Map map, Map importMap, .collect(Collectors.toList()); if (otherRegions.isEmpty()) { - logger.warning("No area or regions found for nationType=" + player.getNationId()); + if (logger.isLoggable(Level.WARNING)) logger.warning("No area or regions found for nationType=" + player.getNationId()); continue; } @@ -370,7 +371,7 @@ private void makeNativeSettlements(final Map map, Map importMap, .collect(Collectors.toCollection(LinkedHashSet::new)); if (settlementTilesForNation.isEmpty()) { - logger.warning("No settlements in region for nationType=" + player.getNationId()); + if (logger.isLoggable(Level.WARNING)) logger.warning("No settlements in region for nationType=" + player.getNationId()); } designatedArea.put(player, settlementTilesForNation); } diff --git a/src/net/sf/freecol/server/model/DiplomacySession.java b/src/net/sf/freecol/server/model/DiplomacySession.java index 15797585fd..397331d3f5 100644 --- a/src/net/sf/freecol/server/model/DiplomacySession.java +++ b/src/net/sf/freecol/server/model/DiplomacySession.java @@ -33,6 +33,7 @@ import net.sf.freecol.common.networking.ChangeSet.See; import net.sf.freecol.common.networking.CloseMessage; import net.sf.freecol.common.networking.DiplomacyMessage; +import java.util.logging.Level; /** @@ -273,7 +274,7 @@ private static DiplomacySession findContactSession(Player p1, Player p2) { * @param cs A {@code ChangeSet} to update. */ private void completeInternal(boolean result, ChangeSet cs) { - logger.info("Completing diplomacy session: " + this); + if (logger.isLoggable(Level.INFO)) logger.info("Completing diplomacy session: " + this); if (this.agreement != null) { // Agreement is null in first contact if (result) { result = getGame().csAcceptTrade(this.agreement, this.unit, diff --git a/src/net/sf/freecol/server/model/LootSession.java b/src/net/sf/freecol/server/model/LootSession.java index 3fc798b40d..163fde7b22 100644 --- a/src/net/sf/freecol/server/model/LootSession.java +++ b/src/net/sf/freecol/server/model/LootSession.java @@ -24,8 +24,6 @@ import net.sf.freecol.common.model.Goods; import net.sf.freecol.common.model.Unit; import net.sf.freecol.common.networking.ChangeSet; - - /** * A type of session to handle looting of cargo. */ @@ -40,13 +38,15 @@ public LootSession(Unit winner, Unit loser, List capture) { this.capture = capture; } + public List getCapture() { + return capture; + } + /** + * {@inheritDoc} + */ @Override public boolean complete(ChangeSet cs) { return super.complete(cs); } - - public List getCapture() { - return capture; - } } diff --git a/src/net/sf/freecol/server/model/ServerBuilding.java b/src/net/sf/freecol/server/model/ServerBuilding.java index 2b0d2deda5..ae76f75850 100644 --- a/src/net/sf/freecol/server/model/ServerBuilding.java +++ b/src/net/sf/freecol/server/model/ServerBuilding.java @@ -40,6 +40,7 @@ import net.sf.freecol.common.networking.ChangeSet.See; import static net.sf.freecol.common.util.CollectionUtils.*; import net.sf.freecol.common.util.LogBuilder; +import java.util.logging.Level; /** @@ -120,16 +121,14 @@ public boolean csCheckTeach(Unit teacher, ChangeSet cs) { final Player owner = getColony().getOwner(); Unit student = teacher.getStudent(); - if (student != null - && teacher.getTurnsOfTraining() - >= teacher.getNeededTurnsOfTraining()) { - csTrainStudent(teacher, student, cs); - // Student will have changed, teacher already added in csTeach - cs.add(See.only(owner), student); - if (teacher.getStudent() == null) csAssignStudent(teacher, cs); - return true; - } - return false; + if (student == null + || teacher.getTurnsOfTraining() + < teacher.getNeededTurnsOfTraining()) return false; + csTrainStudent(teacher, student, cs); + // Student will have changed, teacher already added in csTeach + cs.add(See.only(owner), student); + if (teacher.getStudent() == null) csAssignStudent(teacher, cs); + return true; } /** @@ -146,7 +145,7 @@ private boolean csTrainStudent(Unit teacher, Unit student, ChangeSet cs) { UnitType skill = student.getTeachingType(teacher); boolean ret = skill != null; if (skill == null) { - logger.warning("Student " + student.getId() + if (logger.isLoggable(Level.WARNING)) logger.warning("Student " + student.getId() + " can not learn from " + teacher.getId()); } else { student.changeType(skill);//-vis: safe within colony diff --git a/src/net/sf/freecol/server/model/ServerColony.java b/src/net/sf/freecol/server/model/ServerColony.java index 0fc8e4750a..09e83758e1 100644 --- a/src/net/sf/freecol/server/model/ServerColony.java +++ b/src/net/sf/freecol/server/model/ServerColony.java @@ -63,6 +63,7 @@ import net.sf.freecol.common.networking.ChangeSet; import net.sf.freecol.common.networking.ChangeSet.See; import net.sf.freecol.common.util.LogBuilder; +import java.util.logging.Level; /** @@ -173,7 +174,7 @@ private Unit csBuildUnit(BuildQueue buildQueue, .addStringTemplate("%unit%", unit.getLabel())); } - logger.info("New unit in " + getName() + ": " + type.getSuffix()); + if (logger.isLoggable(Level.INFO)) logger.info("New unit in " + getName() + ": " + type.getSuffix()); return unit; } @@ -240,7 +241,7 @@ private boolean csBuildBuilding(BuildQueue buildQueue, if (owner.isAI()) { firePropertyChange(REARRANGE_COLONY, true, false); } - logger.info("New building in " + getName() + if (logger.isLoggable(Level.INFO)) logger.info("New building in " + getName() + ": " + type.getSuffix()); } return success; @@ -290,7 +291,7 @@ private BuildableType csNextBuildable(BuildQueue queue, .addNamed("%building%", buildable)); break; default: // Are there other warnings to send? - logger.warning("Unexpected build failure at " + getName() + if (logger.isLoggable(Level.WARNING)) logger.warning("Unexpected build failure at " + getName() + " for " + buildable + ": " + getNoBuildReason(buildable, null)); cs.addMessage(owner, @@ -491,7 +492,7 @@ public void csAddConvert(Unit brave, ChangeSet cs) { .addStringTemplate("%nation%", nation) .addName("%colony%", getName())); newOwner.invalidateCanSeeTiles();//+vis(other) - logger.fine("Convert at " + getName() + " for " + getName()); + if (logger.isLoggable(Level.FINE)) logger.fine("Convert at " + getName() + " for " + getName()); } } diff --git a/src/net/sf/freecol/server/model/ServerGame.java b/src/net/sf/freecol/server/model/ServerGame.java index 489a558a98..15220fd93f 100644 --- a/src/net/sf/freecol/server/model/ServerGame.java +++ b/src/net/sf/freecol/server/model/ServerGame.java @@ -196,12 +196,12 @@ public void sendToList(List players, ChangeSet cs) { public boolean sendTo(Player player, ChangeSet cs) { try { return player.send(cs); - } catch (Exception e) { + } catch (IllegalStateException e) { // Catch all manner of exceptions here to localize failure // to just one player. Nothing is *expected*, but the // entire output side of serialization is potentially // exercised here, so it is a good place to find new fails. - logger.log(Level.WARNING, "sendTo(" + player.getId() + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "sendTo(" + player.getId() + "," + cs + ") failed", e); } return false; @@ -329,7 +329,7 @@ public void csNextTurn(ChangeSet cs) { Session.completeAll(cs); setTurn(getTurn().next()); - logger.finest("Turn is now " + getTurn() + "/" + duration); + if (logger.isLoggable(Level.FINEST)) logger.finest("Turn is now " + getTurn() + "/" + duration); cs.add(See.all(), new NewTurnMessage(getTurn())); } @@ -442,7 +442,7 @@ private ServerPlayer csSpanishSuccession(ChangeSet cs, LogBuilder lb, ; // Allow carrier to handle } else if (!weakest.csChangeOwner(unit, strongAI, null, null, cs)) { //-vis(both) - logger.warning("Owner change failed for " + unit); + if (logger.isLoggable(Level.WARNING)) logger.warning("Owner change failed for " + unit); } else { unit.setMovesLeft(0); unit.setState(Unit.UnitState.ACTIVE); @@ -520,18 +520,18 @@ public boolean csAcceptTrade(DiplomaticTrade agreement, Unit unit, final Player source = tradeItem.getSource(); final Player dest = tradeItem.getDestination(); if (!tradeItem.isValid()) { - logger.warning("Trade with invalid tradeItem: " + tradeItem); + if (logger.isLoggable(Level.WARNING)) logger.warning("Trade with invalid tradeItem: " + tradeItem); fail = true; continue; } if (source != srcPlayer && source != dstPlayer) { - logger.warning("Trade with invalid source: " + if (logger.isLoggable(Level.WARNING)) logger.warning("Trade with invalid source: " + ((source == null) ? "null" : source.getId())); fail = true; continue; } if (dest != srcPlayer && dest != dstPlayer) { - logger.warning("Trade with invalid destination: " + if (logger.isLoggable(Level.WARNING)) logger.warning("Trade with invalid destination: " + ((dest == null) ? "null" : dest.getId())); fail = true; continue; @@ -539,13 +539,13 @@ public boolean csAcceptTrade(DiplomaticTrade agreement, Unit unit, Colony colony = tradeItem.getColony(getGame()); if (colony != null && !source.owns(colony)) { - logger.warning("Trade with invalid source owner: " + colony); + if (logger.isLoggable(Level.WARNING)) logger.warning("Trade with invalid source owner: " + colony); fail = true; continue; } int gold = tradeItem.getGold(); if (gold > 0 && !source.checkGold(gold)) { - logger.warning("Trade with invalid gold: " + gold); + if (logger.isLoggable(Level.WARNING)) logger.warning("Trade with invalid gold: " + gold); fail = true; continue; } @@ -555,15 +555,15 @@ public boolean csAcceptTrade(DiplomaticTrade agreement, Unit unit, Location loc = goods.getLocation(); if (loc instanceof Ownable && !source.owns((Ownable)loc)) { - logger.warning("Trade with invalid source owner: " + loc); + if (logger.isLoggable(Level.WARNING)) logger.warning("Trade with invalid source owner: " + loc); fail = true; } else if (!(loc instanceof GoodsLocation && loc.contains(goods))) { - logger.warning("Trade of unavailable goods " + goods + if (logger.isLoggable(Level.WARNING)) logger.warning("Trade of unavailable goods " + goods + " at " + loc); fail = true; } else if (dest.owns(unit) && !unit.couldCarry(goods)) { - logger.warning("Trade unit can not carry traded goods: " + if (logger.isLoggable(Level.WARNING)) logger.warning("Trade unit can not carry traded goods: " + goods); fail = true; } @@ -573,11 +573,11 @@ public boolean csAcceptTrade(DiplomaticTrade agreement, Unit unit, Unit u = tradeItem.getUnit(); if (u != null) { if (!source.owns(u)) { - logger.warning("Trade with invalid source owner: " + u); + if (logger.isLoggable(Level.WARNING)) logger.warning("Trade with invalid source owner: " + u); fail = true; continue; } else if (dest.owns(unit) && !unit.couldCarry(u)) { - logger.warning("Trade unit can not carry traded unit: " + if (logger.isLoggable(Level.WARNING)) logger.warning("Trade unit can not carry traded unit: " + u); fail = true; } @@ -596,7 +596,7 @@ public boolean csAcceptTrade(DiplomaticTrade agreement, Unit unit, if (stance != null && source.getStance(dest) != stance && !((ServerPlayer)source).csChangeStance(stance, dest, true, cs)) { - logger.warning("Stance trade failure: " + stance); + if (logger.isLoggable(Level.WARNING)) logger.warning("Stance trade failure: " + stance); } Colony colony = tradeItem.getColony(getGame()); if (colony != null) { @@ -645,7 +645,7 @@ public boolean csAcceptTrade(DiplomaticTrade agreement, Unit unit, .addStringTemplate("%defender%", victim.getNationLabel())); } else { - logger.warning("Incite trade failure: " + victim); + if (logger.isLoggable(Level.WARNING)) logger.warning("Incite trade failure: " + victim); } } ServerUnit newUnit = (ServerUnit)tradeItem.getUnit(); @@ -656,7 +656,7 @@ public boolean csAcceptTrade(DiplomaticTrade agreement, Unit unit, if (unit.isOnCarrier()) { Unit carrier = unit.getCarrier(); if (!carrier.couldCarry(newUnit)) { - logger.warning("Can not add " + newUnit + if (logger.isLoggable(Level.WARNING)) logger.warning("Can not add " + newUnit + " to " + carrier); continue; } diff --git a/src/net/sf/freecol/server/model/ServerIndianSettlement.java b/src/net/sf/freecol/server/model/ServerIndianSettlement.java index b7400fd81e..82e1b4a248 100644 --- a/src/net/sf/freecol/server/model/ServerIndianSettlement.java +++ b/src/net/sf/freecol/server/model/ServerIndianSettlement.java @@ -47,6 +47,7 @@ import static net.sf.freecol.common.util.CollectionUtils.*; import net.sf.freecol.common.util.LogBuilder; import static net.sf.freecol.common.util.RandomUtils.*; +import java.util.logging.Level; @@ -164,7 +165,7 @@ public void csStartTurn(Random random, ChangeSet cs) { float cAlarm = missionary.apply(alarm, turn, Modifier.CONVERSION_ALARM_RATE); convert += cMiss + (cAlarm - alarm); - logger.finest("Conversion at " + getName() + " alarm=" + alarm + if (logger.isLoggable(Level.FINEST)) logger.finest("Conversion at " + getName() + " alarm=" + alarm + " " + convert + " = " + getConvertProgress() + " + " + cMiss + " + " + cAlarm); ServerColony colony = (ServerColony)tile.getNearestSettlement(other, @@ -330,7 +331,7 @@ private boolean csChangeAlarm(Player player, int add, boolean propagate, ((ServerPlayer)getOwner()).csModifyTension(player, ((isCapital()) ? add : add/2), this, cs); } - logger.finest("Alarm at " + getName() + if (logger.isLoggable(Level.FINEST)) logger.finest("Alarm at " + getName() + " toward " + player.getName() + " modified by " + add + " now = " + getAlarm(player).getValue()); diff --git a/src/net/sf/freecol/server/model/ServerPlayer.java b/src/net/sf/freecol/server/model/ServerPlayer.java index 3331bf13a9..a434640b43 100644 --- a/src/net/sf/freecol/server/model/ServerPlayer.java +++ b/src/net/sf/freecol/server/model/ServerPlayer.java @@ -48,6 +48,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Map.Entry; import java.util.Random; import java.util.Set; @@ -332,7 +333,7 @@ public void updateCurrentFather(FoundingFather ff) { setCurrentFather(ff); clearOfferedFathers(); if (ff != null) { - logger.finest(getId() + " is recruiting " + ff.getId() + if (logger.isLoggable(Level.FINEST)) logger.finest(getId() + " is recruiting " + ff.getId() + " in " + getGame().getTurn()); } } @@ -421,7 +422,7 @@ public void randomizeGame(Random random) { } } if (changed) { - logger.finest("randomizeGame(" + getId() + ") initial prices: " + if (logger.isLoggable(Level.FINEST)) logger.finest("randomizeGame(" + getId() + ") initial prices: " + sb.toString().substring(2)); } } @@ -475,8 +476,10 @@ public DeadCheck checkForDeath() { // Traverse player units, look for valid carriers, colonists, // carriers with units, carriers with goods. - boolean hasCarrier = false, hasColonist = false, hasEmbarked = false, - hasGoods = false; + boolean hasCarrier = false; + boolean hasColonist = false; + boolean hasEmbarked = false; + boolean hasGoods = false; for (Unit unit : getUnitSet()) { if (unit.isCarrier()) { if (unit.hasGoodsCargo()) hasGoods = true; @@ -489,17 +492,17 @@ public DeadCheck checkForDeath() { hasColonist = true; // Verify if unit is in new world, or on a carrier in new world - Unit carrier; - if ((carrier = unit.getCarrier()) != null) { + Unit carrier = unit.getCarrier(); + if (carrier != null) { if (carrier.hasTile()) { - logger.info(getName() + " alive, unit " + unit.getId() + if (logger.isLoggable(Level.INFO)) logger.info(getName() + " alive, unit " + unit.getId() + " (embarked) on map."); return DeadCheck.IS_ALIVE; } hasEmbarked = true; } if (unit.hasTile() && !unit.isInMission()) { - logger.info(getName() + " alive, unit " + unit.getId() + if (logger.isLoggable(Level.INFO)) logger.info(getName() + " alive, unit " + unit.getId() + " on map."); return DeadCheck.IS_ALIVE; } @@ -510,17 +513,17 @@ public DeadCheck checkForDeath() { if (getGame().getTurn().getYear() >= mandatory) { // After the season cutover year there must be a presence // in the New World. - logger.info(getName() + " dead, no presence >= " + mandatory); + if (logger.isLoggable(Level.INFO)) logger.info(getName() + " dead, no presence >= " + mandatory); return DeadCheck.IS_DEAD; } // No problems, unit available on carrier but off map, or goods // available to be sold. if (hasEmbarked) { - logger.info(getName() + " alive, has embarked unit."); + if (logger.isLoggable(Level.INFO)) logger.info(getName() + " alive, has embarked unit."); return DeadCheck.IS_ALIVE; } else if (hasGoods) { - logger.info(getName() + " alive, has cargo."); + if (logger.isLoggable(Level.INFO)) logger.info(getName() + " alive, has cargo."); return DeadCheck.IS_ALIVE; } @@ -536,7 +539,7 @@ public DeadCheck checkForDeath() { : min(spec.getUnitTypesWithAbility(Ability.NAVAL_UNIT), unitPricer); if (price == Integer.MAX_VALUE || !checkGold(price)) { - logger.info(getName() + " dead, can not buy carrier."); + if (logger.isLoggable(Level.INFO)) logger.info(getName() + " dead, can not buy carrier."); return DeadCheck.IS_DEAD; } goldNeeded += price; @@ -544,10 +547,10 @@ public DeadCheck checkForDeath() { // A colonist is required. if (hasColonist) { - logger.info(getName() + " alive, has waiting colonist."); + if (logger.isLoggable(Level.INFO)) logger.info(getName() + " alive, has waiting colonist."); return DeadCheck.IS_ALIVE; } else if (europe == null) { - logger.info(getName() + " dead, can not recruit."); + if (logger.isLoggable(Level.INFO)) logger.info(getName() + " dead, can not recruit."); return DeadCheck.IS_DEAD; } int price = Math.min(europe.getCurrentRecruitPrice(), @@ -555,13 +558,13 @@ public DeadCheck checkForDeath() { unitPricer)); goldNeeded += price; if (checkGold(goldNeeded)) { - logger.info(getName() + " alive, can buy colonist."); + if (logger.isLoggable(Level.INFO)) logger.info(getName() + " alive, can buy colonist."); return DeadCheck.IS_ALIVE; } // Col1 auto-recruits a unit in Europe if you run out before // the cutover year. - logger.info(getName() + " survives by autorecruit."); + if (logger.isLoggable(Level.INFO)) logger.info(getName() + " survives by autorecruit."); return DeadCheck.IS_AUTORECRUIT; } @@ -595,7 +598,7 @@ private boolean checkForREFDefeat() { for (Player r : getRebels()) { double rebelLandPower = r.calculateStrength(false); if (rebelLandPower < refLandPower) return false; - logger.fine("REF in trouble wrt " + r.getName() + " (" + if (logger.isLoggable(Level.FINE)) logger.fine("REF in trouble wrt " + r.getName() + " (" + refLandPower + " <= " + rebelLandPower + ")"); } @@ -603,17 +606,15 @@ private boolean checkForREFDefeat() { // a minimal number of land and naval units final int landREFUnitsRequired = 7; // FIXME: magic number if (land < landREFUnitsRequired) { - logger.info("REF surrenders due to land army collapse (" + if (logger.isLoggable(Level.INFO)) logger.info("REF surrenders due to land army collapse (" + land + " < " + landREFUnitsRequired + ")"); return true; } final int navalREFUnitsRequired = 2; // FIXME: magic number - if (naval < navalREFUnitsRequired) { - logger.info("REF surrenders due to lack of naval support (" - + naval + " < " + navalREFUnitsRequired + ")"); - return true; - } - return false; + if (naval >= navalREFUnitsRequired) return false; + if (logger.isLoggable(Level.INFO)) logger.info("REF surrenders due to lack of naval support (" + + naval + " < " + navalREFUnitsRequired + ")"); + return true; } /** @@ -721,19 +722,21 @@ private void csKill(ChangeSet cs) { */ public void csWithdraw(ChangeSet cs, ModelMessage mm, HistoryEvent he) { final Game game = getGame(); - if (mm == null) { + ModelMessage message = mm; + if (message == null) { final String key = (isEuropean()) ? "model.player.dead.european" : "model.player.dead.native"; - mm = new ModelMessage(MessageType.FOREIGN_DIPLOMACY, key, this) + message = new ModelMessage(MessageType.FOREIGN_DIPLOMACY, key, this) .addStringTemplate("%nation%", getNationLabel()); } - if (he == null) { - he = new HistoryEvent(game.getTurn(), HistoryEvent.HistoryEventType.NATION_DESTROYED, null) + HistoryEvent historyEvent = he; + if (historyEvent == null) { + historyEvent = new HistoryEvent(game.getTurn(), HistoryEvent.HistoryEventType.NATION_DESTROYED, null) .addStringTemplate("%nation%", getNationLabel()); } - cs.addGlobalMessage(game, null, mm); - cs.addGlobalHistory(game, he); + cs.addGlobalMessage(game, null, message); + cs.addGlobalHistory(game, historyEvent); csKill(cs);//+vis,+til } @@ -800,7 +803,7 @@ private List getRandomFoundingFathers(Random random) { final Game game = getGame(); final Specification spec = game.getSpecification(); final int age = game.getAge(); - EnumMap>> choices + Map>> choices = new EnumMap<>(FoundingFatherType.class); for (FoundingFather father : transform(spec.getFoundingFathers(), ff -> !hasFather(ff) && ff.isAvailableTo(this))) { @@ -1027,8 +1030,8 @@ public Set collectNewTiles(Stream tiles) { * when making claims. */ public void reassignTiles(Collection tiles, Settlement avoid) { - HashMap votes = new HashMap<>(); - HashMap claims = new HashMap<>(); + Map votes = new HashMap<>(); + Map claims = new HashMap<>(); Settlement claimant; for (Tile tile : tiles) { final Player occupier = (tile.getFirstUnit() == null) ? null @@ -1199,7 +1202,9 @@ public boolean csFlushMarket(ChangeSet cs) { sb.append(' ').append(goodsType.getId()); ret = true; } - if (ret) logger.finest(sb.toString()); + if (ret) { + if (logger.isLoggable(Level.FINEST)) logger.finest(sb.toString()); + } return ret; } @@ -1238,11 +1243,12 @@ public int buyInEurope(Random random, GoodsContainer container, GoodsType type, int amount) { final Market market = getMarket(); int marketAmount = 0; - while (amount > 0) { + int remaining = amount; + while (remaining > 0) { // Always break up into chunks, so the price can adjust // dynamically during large transactions, avoiding // exploitable market manipulation. - int a = (amount <= GoodsContainer.CARGO_SIZE) ? amount + int a = (remaining <= GoodsContainer.CARGO_SIZE) ? remaining : GoodsContainer.CARGO_SIZE; int price = market.getBidPrice(type, a); if (!checkGold(price)) { @@ -1259,7 +1265,7 @@ public int buyInEurope(Random random, GoodsContainer container, market.addGoodsToMarket(type, -ma); marketAmount += ma; propagateToEuropeanMarkets(type, -a, random); - amount -= a; + remaining -= a; } return marketAmount; } @@ -1279,11 +1285,12 @@ public int sellInEurope(Random random, GoodsContainer container, final Market market = getMarket(); final int tax = getTax(); int marketAmount = 0; - while (amount > 0) { + int remaining = amount; + while (remaining > 0) { // Always break up into chunks, so the price can adjust // dynamically during large transactions, avoiding // exploitable market manipulation. - int a = (amount <= GoodsContainer.CARGO_SIZE) ? amount + int a = (remaining <= GoodsContainer.CARGO_SIZE) ? remaining : GoodsContainer.CARGO_SIZE; int incomeBeforeTaxes = market.getSalePrice(type, a); int incomeAfterTaxes = ((100 - tax) * incomeBeforeTaxes) / 100; @@ -1325,7 +1332,7 @@ public int sellInEurope(Random random, GoodsContainer container, market.addGoodsToMarket(type, ma); marketAmount += ma; propagateToEuropeanMarkets(type, a, random); - amount -= a; + remaining -= a; } return marketAmount; } @@ -1362,7 +1369,7 @@ public boolean csChangeStance(Stance stance, Player otherPlayer, cs.addHistory(this, new HistoryEvent(getGame().getTurn(), HistoryEvent.getEventTypeFromStance(stance), otherPlayer) .addStringTemplate("%nation%", otherPlayer.getNationLabel())); - logger.info("Stance modification " + getName() + if (logger.isLoggable(Level.INFO)) logger.info("Stance modification " + getName() + " " + old + " -> " + stance + " wrt " + otherPlayer.getName()); this.addStanceChange(otherPlayer); if (old != Stance.UNCONTACTED) { @@ -1375,29 +1382,32 @@ public boolean csChangeStance(Stance stance, Player otherPlayer, cs.addStance(See.only(otherPlayer), this, stance, otherPlayer); change = true; } - if (symmetric && (old = otherPlayer.getStance(this)) != stance) { - int modifier = old.getTensionModifier(stance); - otherPlayer.setStance(this, stance); - if (modifier != 0) { - ((ServerPlayer)otherPlayer).csModifyTension(this, modifier, cs);//+til - } - cs.addHistory(otherPlayer, new HistoryEvent(getGame().getTurn(), - HistoryEvent.getEventTypeFromStance(stance), this) - .addStringTemplate("%nation%", this.getNationLabel())); - logger.info("Stance modification " + otherPlayer.getName() - + " " + old + " -> " + stance - + " wrt " + getName() + " (symmetric)"); - ((ServerPlayer)otherPlayer).addStanceChange(this); - if (old != Stance.UNCONTACTED) { - cs.addMessage(this, - new ModelMessage(MessageType.FOREIGN_DIPLOMACY, - stance.getStanceChangeKey(), otherPlayer) - .addStringTemplate("%nation%", - otherPlayer.getNationLabel())); + if (symmetric) { + old = otherPlayer.getStance(this); + if (old != stance) { + int modifier = old.getTensionModifier(stance); + otherPlayer.setStance(this, stance); + if (modifier != 0) { + ((ServerPlayer)otherPlayer).csModifyTension(this, modifier, cs);//+til + } + cs.addHistory(otherPlayer, new HistoryEvent(getGame().getTurn(), + HistoryEvent.getEventTypeFromStance(stance), this) + .addStringTemplate("%nation%", this.getNationLabel())); + if (logger.isLoggable(Level.INFO)) logger.info("Stance modification " + otherPlayer.getName() + + " " + old + " -> " + stance + + " wrt " + getName() + " (symmetric)"); + ((ServerPlayer)otherPlayer).addStanceChange(this); + if (old != Stance.UNCONTACTED) { + cs.addMessage(this, + new ModelMessage(MessageType.FOREIGN_DIPLOMACY, + stance.getStanceChangeKey(), otherPlayer) + .addStringTemplate("%nation%", + otherPlayer.getNationLabel())); + } + cs.addStance(See.only(this), otherPlayer, stance, this); + cs.addStance(See.only(otherPlayer), otherPlayer, stance, this); + change = true; } - cs.addStance(See.only(this), otherPlayer, stance, this); - cs.addStance(See.only(otherPlayer), otherPlayer, stance, this); - change = true; } return change; @@ -1577,9 +1587,12 @@ public List csApplyDisaster(Random random, Colony colony, effects.add(effect.getObject()); sb.append(' ').append(Messages.getName(effect.getObject())); } + break; + default: + break; } if (effects.isEmpty()) sb.append(" All avoided"); - logger.fine(sb.toString()); + if (logger.isLoggable(Level.FINE)) logger.fine(sb.toString()); boolean colonyDirty = false; List messages = new ArrayList<>(); @@ -1742,15 +1755,16 @@ public void propagateToEuropeanMarkets(GoodsType type, int amount, int r = (random == null) ? (lowerBound + upperBound)/2 : randomInt(logger, "Propagate goods", random, upperBound - lowerBound + 1) + lowerBound; - amount *= r; - amount /= 100; - if (amount == 0) return; + int adjustedAmount = amount; + adjustedAmount *= r; + adjustedAmount /= 100; + if (adjustedAmount == 0) return; // Do not need to update the clients here, these changes happen // while it is not their turn. for (Player p : getGame().getLiveEuropeanPlayerList(this)) { Market market = p.getMarket(); - if (market != null) market.addGoodsToMarket(type, amount); + if (market != null) market.addGoodsToMarket(type, adjustedAmount); } } @@ -1788,7 +1802,7 @@ public void csYearlyGoodsAdjust(Random random, ChangeSet cs) { amount = randomInt(logger, "Market adjust " + type, random, amount); if (!add) amount = -amount; market.addGoodsToMarket(type, amount); - logger.finest(getName() + " adjust of " + amount + if (logger.isLoggable(Level.FINEST)) logger.finest(getName() + " adjust of " + amount + " " + type + ", total: " + market.getAmountInMarket(type) + ", initial: " + type.getInitialAmount()); @@ -1977,7 +1991,8 @@ public void csAddFoundingFather(FoundingFather father, Random random, final Specification spec = game.getSpecification(); final ServerEurope europe = (ServerEurope)getEurope(); final Turn turn = game.getTurn(); - boolean europeDirty = false, visibilityChange = false; + boolean europeDirty = false; + boolean visibilityChange = false; addFather(father); addHistory(new HistoryEvent(turn, @@ -2173,7 +2188,7 @@ public void csClaimLand(Tile tile, Settlement settlement, int price, true, cs); } } - logger.finest(this.getName() + " claimed " + tile + if (logger.isLoggable(Level.FINEST)) logger.finest(this.getName() + " claimed " + tile + " from " + ((owner == null) ? "no-one" : owner.getName()) + ", price: " + ((price == 0) ? "free" : (price < 0) ? "stolen" : price)); @@ -2257,10 +2272,10 @@ public void csCombat(FreeColGameObject attacker, boolean isBombard = combatModel.combatIsBombard(attacker, defender); Unit attackerUnit = null; Settlement attackerSettlement = null; - Tile attackerTile = null; - Unit defenderUnit = null; - Player defenderPlayer = null; - Tile defenderTile = null; + Tile attackerTile; + Unit defenderUnit; + Player defenderPlayer; + Tile defenderTile; if (isAttack) { attackerUnit = (Unit)attacker; //attackerPlayer = attackerUnit.getOwner(); @@ -2303,11 +2318,12 @@ public void csCombat(FreeColGameObject attacker, // If the combat results were not specified (usually the case), // query the combat model. CombatResult combatResult = null; - if (crs == null) { + List effects = crs; + if (effects == null) { combatResult = combatModel.generateAttackResult(random, attacker, defender); - crs = combatResult.getEffects(); + effects = combatResult.getEffects(); } - if (crs.isEmpty()) { + if (effects.isEmpty()) { throw new RuntimeException("empty attack result: " + this); } @@ -2316,7 +2332,7 @@ public void csCombat(FreeColGameObject attacker, // Set vis so that loser always sees things. // FIXME: Bombard animations See vis; // Visibility that insists on the loser seeing the result. - CombatEffectType result = crs.remove(0); + CombatEffectType result = effects.remove(0); switch (result) { case NO_RESULT: vis = See.perhaps(); @@ -2327,7 +2343,7 @@ public void csCombat(FreeColGameObject attacker, if (attackerTile == null || attackerTile == defenderTile || !attackerTile.isAdjacent(defenderTile)) { - logger.warning("Bogus attack from " + attackerTile + if (logger.isLoggable(Level.WARNING)) logger.warning("Bogus attack from " + attackerTile + " to " + defenderTile); } else { cs.addAttack(vis, attackerUnit, defenderUnit, true); @@ -2340,7 +2356,7 @@ public void csCombat(FreeColGameObject attacker, if (attackerTile == null || attackerTile == defenderTile || !attackerTile.isAdjacent(defenderTile)) { - logger.warning("Bogus attack from " + attackerTile + if (logger.isLoggable(Level.WARNING)) logger.warning("Bogus attack from " + attackerTile + " to " + defenderTile); } else { cs.addAttack(vis, attackerUnit, defenderUnit, false); @@ -2375,7 +2391,7 @@ public void csCombat(FreeColGameObject attacker, defenderTileDirty = true; } - for (CombatEffectType cr : crs) { + for (CombatEffectType cr : effects) { boolean ok; switch (cr) { case AUTOEQUIP_UNIT: @@ -3210,7 +3226,7 @@ private void csDemoteUnit(Unit winner, Unit loser, ChangeSet cs) { UnitTypeChange uc = loser.getUnitChange(UnitChangeType.DEMOTION); if (uc == null || uc.to == loser.getType()) { - logger.warning("Demotion failed, type=" + if (logger.isLoggable(Level.WARNING)) logger.warning("Demotion failed, type=" + ((uc == null) ? "null" : "same type: " + uc.to)); return; } @@ -3380,7 +3396,7 @@ public void csDisposeSettlement(Settlement settlement, ChangeSet cs) { final Player owner = settlement.getOwner(); final Set owned = settlement.getOwnedTiles(); - logger.finest("Disposing of " + settlement.getName()); + if (logger.isLoggable(Level.FINEST)) logger.finest("Disposing of " + settlement.getName()); for (Tile t : owned) t.cacheUnseen();//+til Tile centerTile = settlement.getTile(); ServerPlayer missionaryOwner = null; @@ -3756,7 +3772,7 @@ private void csPillageColony(Unit attacker, Colony colony, private void csDamageBuilding(Building building, ChangeSet cs) { ServerColony colony = (ServerColony)building.getColony(); Tile copied = colony.getTile().getTileToCache(); - boolean changed = false; + boolean changed; BuildingType type = building.getType(); if (type.getUpgradesFrom() == null) { changed = colony.ejectUnits(building, building.getUnitList());//-til @@ -3769,7 +3785,7 @@ private void csDamageBuilding(Building building, ChangeSet cs) { for (WorkLocation wl : transform(colony.getAllWorkLocations(), w -> !w.isEmpty() && !w.canBeWorked())) { changed |= colony.ejectUnits(wl, wl.getUnitList());//-til - logger.info("Units ejected from workLocation " + if (logger.isLoggable(Level.INFO)) logger.info("Units ejected from workLocation " + wl.getId() + " on loss of " + building.getType().getSuffix()); } @@ -3798,7 +3814,7 @@ private void csPromoteUnit(Unit winner, ChangeSet cs) { UnitTypeChange uc = winner.getUnitChange(UnitChangeType.PROMOTION); if (uc == null || uc.to == winner.getType()) { - logger.warning("Promotion failed, type=" + if (logger.isLoggable(Level.WARNING)) logger.warning("Promotion failed, type=" + ((uc == null) ? "null" : "same type: " + uc.to)); return; } @@ -4038,7 +4054,7 @@ public void csRaiseTax(int tax, Goods goods, boolean accepted, if (accepted) { csSetTax(tax, cs); - logger.info("Accepted tax raise to: " + tax); + if (logger.isLoggable(Level.INFO)) logger.info("Accepted tax raise to: " + tax); } else if (colony.getGoodsCount(goodsType) < amount) { // Player has removed the goods from the colony, // so raise the tax anyway. @@ -4049,7 +4065,7 @@ public void csRaiseTax(int tax, Goods goods, boolean accepted, StringTemplate.template(Monarch.MonarchAction.FORCE_TAX.getTextKey()) .addAmount("%amount%", tax + extraTax), getNationId())); - logger.info("Forced tax raise to: " + (tax + extraTax)); + if (logger.isLoggable(Level.INFO)) logger.info("Forced tax raise to: " + (tax + extraTax)); } else { // Tea party Specification spec = getGame().getSpecification(); colony.getGoodsContainer().saveState(); @@ -4079,7 +4095,7 @@ public void csRaiseTax(int tax, Goods goods, boolean accepted, .addAmount("%amount%", amount) .addNamed("%goods%", goodsType)); cs.addAttribute(See.only(this), "flush", Boolean.TRUE.toString()); - logger.info("Goods party at " + colony.getName() + if (logger.isLoggable(Level.INFO)) logger.info("Goods party at " + colony.getName() + " with: " + goods + " arrears: " + arrears); if (isAI()) { // Reset the goods wishes colony.firePropertyChange(Colony.REARRANGE_COLONY, @@ -4234,7 +4250,7 @@ public boolean csContact(Player other, ChangeSet cs) { .addStringTemplate("%nation%", other.getNationLabel())); } - logger.finest("First contact between " + this.getId() + if (logger.isLoggable(Level.FINEST)) logger.finest("First contact between " + this.getId() + " and " + other.getId()); return true; } @@ -4303,7 +4319,7 @@ public void csEuropeanFirstContact(Unit unit, Settlement settlement, unit.setMovesLeft(0); cs.addPartial(See.only(this), unit, "movesLeft", String.valueOf(unit.getMovesLeft())); - logger.info("New European contact for " + unit + if (logger.isLoggable(Level.INFO)) logger.info("New European contact for " + unit + ", with session: " + session.getKey()); } @@ -4328,40 +4344,42 @@ public boolean csChangeOwner(Unit unit, Player newOwner, String change, final Tile oldTile = unit.getTile(); // Undead can not avoid a change override! - if (newOwner.isUndead()) change = UnitChangeType.UNDEAD; - if (change != null) { + String changeType = newOwner.isUndead() ? UnitChangeType.UNDEAD : change; + if (changeType != null) { UnitType mainType = unit.getType(); UnitTypeChange uc; - if ((uc = unit.getUnitChange(change, null, newOwner)) == null) { + uc = unit.getUnitChange(changeType, null, newOwner); + if (uc == null) { ; // mainType is unchanged } else if (uc.isAvailableTo(newOwner)) { mainType = uc.to; } else { // Can not have this unit. - logger.warning("Change type/owner failed for " + unit - + " -> " + newOwner + "(" + change + "/" + uc + ")"); + if (logger.isLoggable(Level.WARNING)) logger.warning("Change type/owner failed for " + unit + + " -> " + newOwner + "(" + changeType + "/" + uc + ")"); ((ServerUnit)unit).csRemove(See.perhaps().always(this), oldTile, cs); return false; } for (Unit u : unit.getUnitList()) { - if ((uc = u.getUnitChange(change, null, newOwner)) == null) { + uc = u.getUnitChange(changeType, null, newOwner); + if (uc == null) { ; // no change for this passenger } else if (uc.isAvailableTo(newOwner)) { if (uc.to != u.getType() && !u.changeType(uc.to)) { - logger.warning("Type change failure: " + u + if (logger.isLoggable(Level.WARNING)) logger.warning("Type change failure: " + u + " -> " + uc.to); } } else { - logger.warning("Change type/owner failed for cargo " + u - + " -> " + newOwner + "(" + change + "/" + uc + ")"); + if (logger.isLoggable(Level.WARNING)) logger.warning("Change type/owner failed for cargo " + u + + " -> " + newOwner + "(" + changeType + "/" + uc + ")"); ((ServerUnit)u).csRemove(See.only(this), unit, cs); } } unit.changeOwner(newOwner); if (mainType != unit.getType() && !unit.changeType(mainType)) { - logger.warning("Type change failure: " + unit + if (logger.isLoggable(Level.WARNING)) logger.warning("Type change failure: " + unit + " -> " + mainType); return false; } @@ -4497,8 +4515,11 @@ public void csNewTurn(Random random, LogBuilder lb, ChangeSet cs) { lb.add("PLAYER ", getName(), ": "); final Game game = getGame(); final Specification spec = getSpecification(); - int oldImmigration = getImmigration(), oldLiberty = getLiberty(), - newSoL = 0, newImmigration = 0, newLiberty = 0; + int oldImmigration = getImmigration(); + int oldLiberty = getLiberty(); + int newSoL = 0; + int newImmigration; + int newLiberty; // Settlements List settlements = getSettlementList(); @@ -4529,7 +4550,7 @@ public void csNewTurn(Random random, LogBuilder lb, ChangeSet cs) { try { ((TurnTaker)unit).csNewTurn(random, lb, cs); } catch (ClassCastException cce) { - logger.log(Level.SEVERE, "Not a ServerUnit: " + unit.getId(), + if (logger.isLoggable(Level.SEVERE)) logger.log(Level.SEVERE, "Not a ServerUnit: " + unit.getId(), cce); } } @@ -4591,7 +4612,7 @@ public void csNewTurn(Random random, LogBuilder lb, ChangeSet cs) { List leftOver = loadShips(land, naval, random);//-vis(this) for (Unit unit : leftOver) { // no use for left over units - logger.warning("Disposing of left over unit " + unit); + if (logger.isLoggable(Level.WARNING)) logger.warning("Disposing of left over unit " + unit); unit.setLocationNoUpdate(null);//-vis: safe, off map unit.dispose();//-vis: safe, never sighted } @@ -4603,7 +4624,7 @@ public void csNewTurn(Random random, LogBuilder lb, ChangeSet cs) { new ModelMessage(MessageType.FOREIGN_DIPLOMACY, "model.player.interventionForceArrives", this)); - logger.info("Intervention force (" + naval.size() + " naval, " + if (logger.isLoggable(Level.INFO)) logger.info("Intervention force (" + naval.size() + " naval, " + land.size() + " land, " + leftOver.size() + " left over) arrives at " + entry + "(for " + port.getName() + ")"); diff --git a/src/net/sf/freecol/server/model/ServerRegion.java b/src/net/sf/freecol/server/model/ServerRegion.java index cdef1d0c84..353f5751a9 100644 --- a/src/net/sf/freecol/server/model/ServerRegion.java +++ b/src/net/sf/freecol/server/model/ServerRegion.java @@ -549,13 +549,25 @@ public static List requireFixedRegions(Map map, LogBuilder lb) { final int midy = maxy / 2; Tile tNP = null, tSP = null, tNA = null, tSA = null, t; for (int y = midy-1; y >= 0; y--) { - if (tNP == null && !(t = map.getTile(0, y)).isLand()) tNP = t; - if (tNA == null && !(t = map.getTile(maxx-1, y)).isLand()) tNA = t; + if (tNP == null) { + t = map.getTile(0, y); + if (!t.isLand()) tNP = t; + } + if (tNA == null) { + t = map.getTile(maxx-1, y); + if (!t.isLand()) tNA = t; + } if (tNP != null && tNA != null) break; } for (int y = midy; y < maxy; y++) { - if (tSP == null && !(t = map.getTile(0, y)).isLand()) tSP = t; - if (tSA == null && !(t = map.getTile(maxx-1, y)).isLand()) tSA = t; + if (tSP == null) { + t = map.getTile(0, y); + if (!t.isLand()) tSP = t; + } + if (tSA == null) { + t = map.getTile(maxx-1, y); + if (!t.isLand()) tSA = t; + } if (tSP != null && tSA != null) break; } int nNP = 0, nSP = 0, nNA = 0, nSA = 0; diff --git a/src/net/sf/freecol/server/model/ServerUnit.java b/src/net/sf/freecol/server/model/ServerUnit.java index 02ef4c3e0e..8e7b778b1f 100644 --- a/src/net/sf/freecol/server/model/ServerUnit.java +++ b/src/net/sf/freecol/server/model/ServerUnit.java @@ -76,6 +76,7 @@ import net.sf.freecol.common.util.RandomChoice; import static net.sf.freecol.common.util.CollectionUtils.*; import static net.sf.freecol.common.util.RandomUtils.*; +import java.util.logging.Level; /** @@ -399,7 +400,7 @@ private Unit getSlowedBy(Tile newTile, Random random) { (int)Math.round(totalAttackPower - defencePower)); int moves = Math.min(9, 3 + diff / 3); setMovesLeft(getMovesLeft() - moves); - logger.info(getId() + " slowed by " + attacker.getId() + if (logger.isLoggable(Level.INFO)) logger.info(getId() + " slowed by " + attacker.getId() + " by " + Integer.toString(moves) + " moves."); } else { attacker = null; @@ -507,7 +508,7 @@ private boolean csExploreLostCityRumour(Random random, ChangeSet cs) { } } - logger.info("Unit " + getId() + " is exploring rumour " + rumour); + if (logger.isLoggable(Level.INFO)) logger.info("Unit " + getId() + " is exploring rumour " + rumour); boolean result = true; String key = rumour.getDescriptionKey(); switch (rumour) { @@ -636,7 +637,7 @@ private boolean csExploreLostCityRumour(Random random, ChangeSet cs) { break; case NO_SUCH_RUMOUR: case MOUNDS: default: - logger.warning("Bogus rumour type: " + rumour); + if (logger.isLoggable(Level.WARNING)) logger.warning("Bogus rumour type: " + rumour); break; } tile.cacheUnseen();//+til @@ -718,7 +719,7 @@ public void csNewContactCheck(Tile newTile, boolean firstLanding, this, is) .addStringTemplate("%nation%", nation) .addName("%settlement%", is.getName())); - logger.finest("First contact between " + if (logger.isLoggable(Level.FINEST)) logger.finest("First contact between " + contactPlayer.getId() + " and " + is + " at " + newTile); } @@ -757,7 +758,7 @@ public void csMove(Tile newTile, Random random, ChangeSet cs) { if (oldLocation == null) { // This "can not happen", but if it did what follows would crash. // Probably best to log and return in the hope of not breaking it worse. - logger.warning("Unit with null location: " + this.toString()); + if (logger.isLoggable(Level.WARNING)) logger.warning("Unit with null location: " + this.toString()); return; } Set oldTiles = getVisibleTileSet(); @@ -772,7 +773,7 @@ public void csMove(Tile newTile, Random random, ChangeSet cs) { setMovesLeft(0); // Disembark always consumes all moves. } else { if (getMoveCost(newTile) <= 0) { - logger.warning("Move of unit: " + getId() + if (logger.isLoggable(Level.WARNING)) logger.warning("Move of unit: " + getId() + " from: " + oldLocation.getTile().getId() + " to: " + newTile.getId() + " has bogus cost: " + getMoveCost(newTile)); @@ -831,7 +832,7 @@ && randomInt(logger, "Claim tribal land", random, d + 1) == 0) { } // Check for first landing - String newLand = null; + String newLand; boolean firstLanding = !owner.isNewLandNamed(); if (firstLanding && owner.isEuropean()) { newLand = owner.getNameForNewLand(); @@ -840,7 +841,7 @@ && randomInt(logger, "Claim tribal land", random, d + 1) == 0) { owner.setNewLandName(newLand); cs.add(See.only(owner), new NewLandNameMessage(this, newLand)); - logger.finest("First landing for " + owner + if (logger.isLoggable(Level.FINEST)) logger.finest("First landing for " + owner + " at " + newTile + " with " + this); } @@ -1043,7 +1044,8 @@ && randomInt(logger, "Experience", random, maxValue) int amount = (getType().hasAbility(Ability.EXPERT_PIONEER)) ? 2 : 1; int turns = ti.getTurnsToComplete(); - if ((turns -= amount) < 0) turns = 0; + turns -= amount; + if (turns < 0) turns = 0; ti.setTurnsToComplete(turns); setWorkLeft(turns); if (ti.isRoad() && ti.isComplete()) { @@ -1093,7 +1095,7 @@ && randomInt(logger, "Experience", random, maxValue) locDirty = true; } else { if (!(result instanceof Tile)) { - logger.warning("Unit has unsupported destination: " + if (logger.isLoggable(Level.WARNING)) logger.warning("Unit has unsupported destination: " + dst + " -> " + result); result = getFullEntryLocation(); } diff --git a/src/net/sf/freecol/server/model/Session.java b/src/net/sf/freecol/server/model/Session.java index 649c99fdeb..44579966f1 100644 --- a/src/net/sf/freecol/server/model/Session.java +++ b/src/net/sf/freecol/server/model/Session.java @@ -30,12 +30,13 @@ import net.sf.freecol.common.model.FreeColGameObject; import net.sf.freecol.common.networking.ChangeSet; +import java.util.logging.Level; /** * Root class for sessions. */ -public abstract class Session { +public class Session { private static final Logger logger = Logger.getLogger(Session.class.getName()); @@ -46,7 +47,7 @@ public abstract class Session { private String key; /** Has this session been completed? */ - private boolean completed = false; + private boolean completed; /** @@ -63,7 +64,7 @@ protected Session(String key) { } this.key = key; this.completed = false; - logger.finest("Created session: " + key); + if (logger.isLoggable(Level.FINEST)) logger.finest("Created session: " + key); } @@ -248,4 +249,3 @@ public static T lookup(Class type, String key) { return (ts == null) ? null : type.cast(ts); } } - diff --git a/src/net/sf/freecol/server/model/TurnTaker.java b/src/net/sf/freecol/server/model/TurnTaker.java index 4d98cba8e5..fc209528ad 100644 --- a/src/net/sf/freecol/server/model/TurnTaker.java +++ b/src/net/sf/freecol/server/model/TurnTaker.java @@ -28,6 +28,7 @@ /** * Interface for server-side objects which need to update every turn. */ +@FunctionalInterface public interface TurnTaker { /** diff --git a/src/net/sf/freecol/server/networking/Server.java b/src/net/sf/freecol/server/networking/Server.java index 5833dc0924..7f80a1ffa8 100644 --- a/src/net/sf/freecol/server/networking/Server.java +++ b/src/net/sf/freecol/server/networking/Server.java @@ -30,6 +30,9 @@ import java.util.logging.Level; import java.util.logging.Logger; +import javax.xml.stream.XMLStreamException; + +import net.sf.freecol.common.FreeColException; import net.sf.freecol.FreeCol; import net.sf.freecol.common.networking.Connection; import net.sf.freecol.common.networking.Message; @@ -202,11 +205,11 @@ public void sendToAll(Message message, Connection exceptConnection) { if (conn.isAlive()) { try { conn.sendMessage(message); - } catch (Exception ex) { - logger.log(Level.WARNING, "Unable to send to: " + conn, ex); + } catch (FreeColException | IOException | XMLStreamException ex) { + if (logger.isLoggable(Level.WARNING)) logger.log(Level.WARNING, "Unable to send to: " + conn, ex); } } else { - logger.log(Level.INFO, "Reap dead connection: " + conn); + if (logger.isLoggable(Level.INFO)) logger.log(Level.INFO, "Reap dead connection: " + conn); removeConnection(conn); } } @@ -262,10 +265,8 @@ public void run() { // Undocumented null return has been seen this.freeColServer.addNewUserConnection(sock); } - } catch (Exception ex) { - // Catch all exceptions. There have been - // sightings of spurious NPEs and other fail in - // the Java libraries. + } catch (FreeColException | IOException | XMLStreamException + | SecurityException ex) { if (this.running) { logger.log(Level.WARNING, "Connection failed: ", ex); } diff --git a/src/net/sf/freecol/tools/ColonizationMapReader.java b/src/net/sf/freecol/tools/ColonizationMapReader.java index 78c9317944..0c0e8103b3 100644 --- a/src/net/sf/freecol/tools/ColonizationMapReader.java +++ b/src/net/sf/freecol/tools/ColonizationMapReader.java @@ -22,6 +22,8 @@ import java.io.EOFException; import java.io.RandomAccessFile; import java.util.Arrays; +import java.util.logging.Level; +import java.util.logging.Logger; /** @@ -59,6 +61,9 @@ */ public class ColonizationMapReader { + private static final Logger logger + = Logger.getLogger(ColonizationMapReader.class.getName()); + public static final int WIDTH = 0; public static final int HEIGHT = 2; @@ -139,25 +144,28 @@ public static void main(String[] args) throws Exception { try { reader.readFully(header); } catch (EOFException ee) { - System.err.println("Unable to read header of " + args[0] - + ": " + ee); + if (logger.isLoggable(Level.SEVERE)) logger.log(Level.SEVERE, "Unable to read header of " + + args[0] + ": " + ee, ee); System.exit(1); } - System.out.println(String.format("Map width: %02d", (int) header[WIDTH])); - System.out.println(String.format("Map height: %02d", (int) header[HEIGHT])); + if (logger.isLoggable(Level.INFO)) logger.info(String.format("Map width: %02d", + (int) header[WIDTH])); + if (logger.isLoggable(Level.INFO)) logger.info(String.format("Map height: %02d", + (int) header[HEIGHT])); int size = header[WIDTH] * header[HEIGHT]; layer1 = new byte[size]; try { reader.readFully(layer1); } catch (EOFException ee) { - System.err.println("Unable to read data of " + args[0] - + ": " + ee); + if (logger.isLoggable(Level.SEVERE)) logger.log(Level.SEVERE, "Unable to read data of " + + args[0] + ": " + ee, ee); System.exit(1); } int index = 0; for (int y = 0; y < header[HEIGHT]; y++) { + StringBuilder row = new StringBuilder(); for (int x = 0; x < header[WIDTH]; x++) { int decimal = layer1[index] & 0xff; char terrain = tiletypes[decimal & 31]; @@ -178,12 +186,12 @@ public static void main(String[] args) throws Exception { default: break; }; - System.out.print(terrain); + row.append(terrain); index++; } - System.out.println('\n'); + if (logger.isLoggable(Level.INFO)) logger.info(row.toString()); } - System.out.println('\n'); + logger.info(""); } } } diff --git a/src/net/sf/freecol/tools/ColonizationSaveGameReader.java b/src/net/sf/freecol/tools/ColonizationSaveGameReader.java index 575dcfe1e1..4f26a8361c 100644 --- a/src/net/sf/freecol/tools/ColonizationSaveGameReader.java +++ b/src/net/sf/freecol/tools/ColonizationSaveGameReader.java @@ -23,10 +23,15 @@ import java.io.RandomAccessFile; import java.nio.charset.StandardCharsets; import java.util.Arrays; +import java.util.logging.Logger; +import java.util.logging.Level; public class ColonizationSaveGameReader { + private static final Logger logger + = Logger.getLogger(ColonizationSaveGameReader.class.getName()); + private final static int PLAYER_DATA = 0x9e; private final static int COLONY_DATA = 0x186; private final static String[] NATIONS = { @@ -48,9 +53,9 @@ public GameData(byte[] data) { } public void print() { - System.out.println("Map size is " + mapWidth + " x " + mapHeight); - System.out.println("Difficulty is " + difficulty); - System.out.println(numberOfColonies + " colonies found"); + if (logger.isLoggable(Level.INFO)) logger.info("Map size is " + mapWidth + " x " + mapHeight); + if (logger.isLoggable(Level.INFO)) logger.info("Difficulty is " + difficulty); + if (logger.isLoggable(Level.INFO)) logger.info(numberOfColonies + " colonies found"); } public int getNumberOfColonies() { @@ -73,9 +78,9 @@ public PlayerData(byte[] data, int offset) { } public void print() { - System.out.println("Player name is " + playerName - + (humanPlayer ? " [human]" : " [AI]")); - System.out.println("New land name is " + newLandName); + if (logger.isLoggable(Level.INFO)) logger.info("Player name is " + playerName + + (humanPlayer ? " [human]" : " [AI]")); + if (logger.isLoggable(Level.INFO)) logger.info("New land name is " + newLandName); } } @@ -116,8 +121,8 @@ public ColonyData(byte[] data, int offset) { } public void print() { - System.out.println(name + " [" + x + ", " + y + "], " - + numberOfColonists + " colonists"); + if (logger.isLoggable(Level.INFO)) logger.info(name + " [" + x + ", " + y + "], " + + numberOfColonists + " colonists"); for (Colonist colonist : colonists) { colonist.print(); } @@ -177,8 +182,8 @@ public Colonist(int occupation, int speciality, int tile) { public void print() { String tileString = (tile >= 0) ? " [tile " + TILES[tile] + "]" : ""; - System.out.println(OCCUPATION[speciality] + " working as " - + OCCUPATION[occupation] + tileString); + if (logger.isLoggable(Level.INFO)) logger.info(OCCUPATION[speciality] + " working as " + + OCCUPATION[occupation] + tileString); } } @@ -198,7 +203,7 @@ public static void main(String[] args) throws Exception { reader.readFully(data); new ColonizationSaveGameReader(data).run(); } catch (EOFException ee) { - System.err.println("Could not read from " + args[0] + ": " + ee); + if (logger.isLoggable(Level.SEVERE)) logger.severe("Could not read from " + args[0] + ": " + ee); System.exit(1); } } @@ -209,7 +214,7 @@ private void run() { GameData gameData = new GameData(data); gameData.print(); for (int index = 0; index < 4; index++) { - System.out.println("Nation is " + NATIONS[index]); + if (logger.isLoggable(Level.INFO)) logger.info("Nation is " + NATIONS[index]); PlayerData playerData = new PlayerData(data, PLAYER_DATA + index * PlayerData.LENGTH); playerData.print(); diff --git a/src/net/sf/freecol/tools/DesktopEntry.java b/src/net/sf/freecol/tools/DesktopEntry.java index 44557cbc86..5ef494791f 100644 --- a/src/net/sf/freecol/tools/DesktopEntry.java +++ b/src/net/sf/freecol/tools/DesktopEntry.java @@ -26,8 +26,10 @@ import java.io.IOException; import java.io.Reader; import java.io.Writer; +import java.util.logging.Logger; import net.sf.freecol.common.util.Utils; +import java.util.logging.Level; /** @@ -35,6 +37,8 @@ */ public class DesktopEntry { + private static final Logger logger = Logger.getLogger(DesktopEntry.class.getName()); + private static final File SOURCE_DIRECTORY = new File("data", "strings"); @@ -70,14 +74,13 @@ public boolean accept(File dir, String name) { } }); if (sourceFiles == null) { - System.err.println("No messages files found in " - + SOURCE_DIRECTORY); + if (logger.isLoggable(Level.SEVERE)) logger.severe("No messages files found in " + SOURCE_DIRECTORY); System.exit(1); } for (String name : sourceFiles) { - System.out.println("Processing source file: " + name); + if (logger.isLoggable(Level.INFO)) logger.info("Processing source file: " + name); String languageCode = null; if (name.startsWith("FreeColMessages_")) { @@ -128,4 +131,3 @@ public boolean accept(File dir, String name) { } } - diff --git a/src/net/sf/freecol/tools/FSGConverter.java b/src/net/sf/freecol/tools/FSGConverter.java index f7f1cb02ee..a1cf89eab5 100644 --- a/src/net/sf/freecol/tools/FSGConverter.java +++ b/src/net/sf/freecol/tools/FSGConverter.java @@ -27,6 +27,7 @@ import java.io.OutputStream; import java.nio.charset.StandardCharsets; import java.nio.file.Files; +import java.util.logging.Logger; import java.util.zip.GZIPInputStream; import net.sf.freecol.FreeCol; @@ -40,6 +41,8 @@ */ public class FSGConverter { + private static final Logger logger = Logger.getLogger(FSGConverter.class.getName()); + /** * A singleton object of this class. * @see #getFSGConverter() @@ -114,7 +117,7 @@ private void convertToXML(InputStream ins, OutputStream outs) in.mark(10); byte[] buf = new byte[5]; if (in.read(buf, 0, buf.length) < buf.length) { - System.err.println("Unable to read header"); + logger.severe("Unable to read header"); return; } in.reset(); @@ -168,13 +171,13 @@ private void convertToXML(InputStream ins, OutputStream outs) * Prints the usage of this program to standard out. */ private static void printUsage() { - System.out.println("A program for converting FreeCol Savegames."); - System.out.println(); - System.out.println("Usage: java -cp FreeCol.jar net.sf.freecol.tools.FSGConverter [-][-]output:xml FSG_FILE [OUTPUT_FILE]"); - System.out.println(); - System.out.println("output:xml \tThe output will be indented XML."); - System.out.println(); - System.out.println("The output file will get the same name as FSG_FILE if not specified (with \".fsg\" replaced with \".xml\")."); + logger.info("A program for converting FreeCol Savegames."); + logger.info(""); + logger.info("Usage: java -cp FreeCol.jar net.sf.freecol.tools.FSGConverter [-][-]output:xml FSG_FILE [OUTPUT_FILE]"); + logger.info(""); + logger.info("output:xml \tThe output will be indented XML."); + logger.info(""); + logger.info("The output file will get the same name as FSG_FILE if not specified (with \".fsg\" replaced with \".xml\")."); } /** diff --git a/src/net/sf/freecol/tools/ForestMaker.java b/src/net/sf/freecol/tools/ForestMaker.java index 6f46f82cb2..10f2e99b8c 100644 --- a/src/net/sf/freecol/tools/ForestMaker.java +++ b/src/net/sf/freecol/tools/ForestMaker.java @@ -32,6 +32,8 @@ import java.util.Comparator; import java.util.List; import java.util.Random; +import java.util.logging.Level; +import java.util.logging.Logger; import javax.imageio.ImageIO; @@ -41,6 +43,8 @@ */ public class ForestMaker { + private static final Logger logger = Logger.getLogger(ForestMaker.class.getName()); + private static final String DESTDIR = "data/rules/classic/resources/images/forest"; private static final int BASE_WIDTH = 128; @@ -120,9 +124,9 @@ public int hashCode() { public static void main(String[] args) throws IOException { if (args.length == 0) { - System.out.println("Usage: ForestMaker ..."); - System.out.println("Directory name should match a directory in"); - System.out.println(" " + DESTDIR); + logger.info("Usage: ForestMaker ..."); + logger.info("Directory name should match a directory in"); + logger.info(" " + DESTDIR); System.exit(1); } @@ -137,23 +141,23 @@ public static void main(String[] args) throws IOException { for (String arg : args) { File sourceDirectory = new File(arg); if (!sourceDirectory.exists()) { - System.out.println("Source directory " + arg + " does not exist."); + if (logger.isLoggable(Level.INFO)) logger.info("Source directory " + arg + " does not exist."); continue; } String baseName = sourceDirectory.getName(); File destinationDirectory = new File(DESTDIR, baseName); if (!destinationDirectory.exists()) { - System.out.println("Destination directory " + if (logger.isLoggable(Level.INFO)) logger.info("Destination directory " + destinationDirectory.getPath() + " does not exist."); continue; } File[] imageFiles = sourceDirectory.listFiles(); if (imageFiles == null) { - System.out.println("No images found in source directory " + if (logger.isLoggable(Level.INFO)) logger.info("No images found in source directory " + arg + "."); continue; } else { - System.out.println(imageFiles.length + if (logger.isLoggable(Level.INFO)) logger.info(imageFiles.length + " images found in source directory " + arg + "."); } List images = new ArrayList<>(imageFiles.length); @@ -165,8 +169,8 @@ public static void main(String[] args) throws IOException { images.add(image); maximumHeight = Math.min(image.getHeight(), maximumHeight); } catch(IOException e) { - System.err.println("Unable to load image " - + imageFile.getName() + ":\n" + e); + if (logger.isLoggable(Level.SEVERE)) logger.log(Level.SEVERE, "Unable to load image " + + imageFile.getName(), e); } } } @@ -289,7 +293,7 @@ tile bounds (this will fail if the tree && crown < -BASE_HEIGHT + RIVER_HEIGHT - (x - halfWidth) / 2) { continue; } - //System.out.println("x=" + x + ", y=" + (y - height)); + //logger.info("x=" + x + ", y=" + (y - height)); trees.add(new ImageLocation(image, x - halfWidth, crown)); count++; } @@ -321,4 +325,3 @@ private static int getRandomY(Random random, int x) { return (height == 0) ? 0 : random.nextInt(2 * height) - height; }*/ } - diff --git a/src/net/sf/freecol/tools/GenerateDocumentation.java b/src/net/sf/freecol/tools/GenerateDocumentation.java index dabe2c7004..2129720667 100644 --- a/src/net/sf/freecol/tools/GenerateDocumentation.java +++ b/src/net/sf/freecol/tools/GenerateDocumentation.java @@ -27,6 +27,8 @@ import java.util.Arrays; import java.util.HashMap; import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; @@ -47,6 +49,8 @@ */ public class GenerateDocumentation { + private static final Logger logger = Logger.getLogger(GenerateDocumentation.class.getName()); + private static final File STRING_DIRECTORY = new File("data/strings"); private static final File RESOURCE_DIRECTORY = new File("data/default"); private static final File RULE_DIRECTORY = new File("data/rules/classic"); @@ -79,7 +83,7 @@ public static void main(String[] args) { } private static void readResources() { - System.out.println("Processing source file: resources.properties"); + logger.info("Processing source file: resources.properties"); File sourceFile = new File(RESOURCE_DIRECTORY, "resources.properties"); try ( Reader reader = Utils.getFileUTF8Reader(sourceFile); @@ -96,7 +100,7 @@ private static void readResources() { line = bufferedReader.readLine(); } } catch (IOException ioe) { - System.err.println("Error reading resources: " + ioe); + logger.log(Level.SEVERE, "Error reading resources", ioe); } } @@ -107,7 +111,7 @@ private static void generateTMX() { for (String name : sourceFiles) { - System.out.println("Processing source file: " + name); + logger.info("Processing source file: " + name); String languageCode = name.substring(15, name.length() - 11); if (languageCode.isEmpty()) { @@ -171,7 +175,7 @@ private static void generateTMX() { } */ - private static void generateDocumentation(String[] languages) { + private static void generateDocumentation(String... languages) { for (String name : sourceFiles) { String languageCode = name.substring(15, name.length() - 11); @@ -180,7 +184,7 @@ private static void generateDocumentation(String[] languages) { } else if ('_' == languageCode.charAt(0)) { languageCode = languageCode.substring(1); if ("qqq".equals(languageCode)) { - System.out.println("Skipping language code 'qqq'"); + logger.info("Skipping language code 'qqq'"); continue; } } else { @@ -189,7 +193,7 @@ private static void generateDocumentation(String[] languages) { } if (languages.length == 0 || Arrays.binarySearch(languages, languageCode) >= 0) { - System.out.println("Generating localized documentation for language code " + if (logger.isLoggable(Level.INFO)) logger.info("Generating localized documentation for language code " + languageCode); Messages.loadMessageBundle(Messages.getLocale(languageCode)); @@ -202,8 +206,8 @@ private static void generateDocumentation(String[] languages) { try { stylesheet = factory.newTransformer(xsl); } catch (TransformerException tce) { - System.err.println("Problem with " + XSL + " at: " - + tce.getLocationAsString() + '\n' + tce); + if (logger.isLoggable(Level.SEVERE)) logger.log(Level.SEVERE, "Problem with " + XSL + " at: " + + tce.getLocationAsString(), tce); continue; } @@ -213,7 +217,7 @@ private static void generateDocumentation(String[] languages) { stylesheet.transform(request, response); } catch (TransformerException e) { - System.err.println("Transformation error: " + e); + logger.log(Level.SEVERE, "Transformation error", e); } } } diff --git a/src/net/sf/freecol/tools/InstallerTranslations.java b/src/net/sf/freecol/tools/InstallerTranslations.java index 6d4396b7ab..d3c568368b 100644 --- a/src/net/sf/freecol/tools/InstallerTranslations.java +++ b/src/net/sf/freecol/tools/InstallerTranslations.java @@ -27,6 +27,8 @@ import java.io.Writer; import java.util.HashMap; import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; import net.sf.freecol.common.util.Utils; @@ -36,6 +38,8 @@ */ public class InstallerTranslations { + private static final Logger logger = Logger.getLogger(InstallerTranslations.class.getName()); + private static final File SOURCE_DIRECTORY = new File("data/strings"); private static final File MAIN_FILE = @@ -104,26 +108,24 @@ public static void main(String[] args) throws Exception { /* if (!LANGUAGE_CODES.exists()) { - System.out.println("Language codes not found."); + logger.info("Language codes not found."); System.exit(1); } */ if (!MAIN_FILE.exists()) { - System.err.println("Main input file not found."); + logger.severe("Main input file not found."); System.exit(1); } if (!DESTINATION_DIRECTORY.exists()) { try { if (!DESTINATION_DIRECTORY.mkdirs()) { - System.err.println("Could not create " - + DESTINATION_DIRECTORY); + if (logger.isLoggable(Level.SEVERE)) logger.severe("Could not create " + DESTINATION_DIRECTORY); System.exit(1); } } catch (SecurityException se) { - System.err.println("Could not create " + DESTINATION_DIRECTORY - + ": " + se); + if (logger.isLoggable(Level.SEVERE)) logger.log(Level.SEVERE, "Could not create " + DESTINATION_DIRECTORY, se); System.exit(1); } } @@ -143,13 +145,13 @@ public boolean accept(File dir, String name) { } }); if (sourceFiles == null) { - System.err.println("No messages files found in " + SOURCE_DIRECTORY); + if (logger.isLoggable(Level.SEVERE)) logger.severe("No messages files found in " + SOURCE_DIRECTORY); System.exit(1); } for (String name : sourceFiles) { - String languageCode = null; + String languageCode; int index = name.indexOf('.', 16); if (index < 0) { continue; @@ -166,11 +168,11 @@ public boolean accept(File dir, String name) { } if (languageCode == null) { - System.out.println("Skipping source file: " + name); + if (logger.isLoggable(Level.INFO)) logger.info("Skipping source file: " + name); continue; } - System.out.println("Processing source file: " + name); + if (logger.isLoggable(Level.INFO)) logger.info("Processing source file: " + name); File sourceFile = new File(SOURCE_DIRECTORY, name); Map sourceProperties = readFile(sourceFile); @@ -218,8 +220,7 @@ private static Map readFile(File file) { line = bufferedReader.readLine(); } } catch (IOException ioe) { - System.err.println("Error reading file: " + file.getName() - + ": " + ioe); + if (logger.isLoggable(Level.SEVERE)) logger.log(Level.SEVERE, "Error reading file: " + file.getName(), ioe); } return result; } @@ -245,4 +246,3 @@ private static Map readLanguageMappings(File file) { } */ } - diff --git a/src/net/sf/freecol/tools/MapConverter.java b/src/net/sf/freecol/tools/MapConverter.java index 860b7ebef9..7c0f1f7b2c 100644 --- a/src/net/sf/freecol/tools/MapConverter.java +++ b/src/net/sf/freecol/tools/MapConverter.java @@ -24,6 +24,8 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; +import java.util.logging.Level; +import java.util.logging.Logger; import javax.imageio.ImageIO; import javax.xml.stream.XMLStreamException; @@ -41,6 +43,8 @@ */ public class MapConverter { + private static final Logger logger = Logger.getLogger(MapConverter.class.getName()); + public static void main(String[] args) throws Exception { FreeColRules.loadRules(); @@ -53,36 +57,34 @@ public static void main(String[] args) throws Exception { String newName = filename + ".old"; File in = new File(newName); if (!out.renameTo(in)) { - System.err.println("Could not rename " + filename - + " to " + newName); + if (logger.isLoggable(Level.SEVERE)) logger.severe("Could not rename " + filename + " to " + newName); continue; } - System.out.println("Renamed " + filename + " to " + newName + "."); + if (logger.isLoggable(Level.INFO)) logger.info("Renamed " + filename + " to " + newName + "."); FreeColSavegameFile savegame = new FreeColSavegameFile(in); BufferedImage thumbnail = null; try (InputStream thumbnailIn = savegame.getInputStream(FreeColSavegameFile.THUMBNAIL_FILE)) { thumbnail = ImageIO.read(thumbnailIn); - System.out.println("Loaded thumbnail."); + logger.info("Loaded thumbnail."); } catch (FileNotFoundException e) { - System.err.println("No thumbnail present."); + logger.warning("No thumbnail present."); } FreeColServer server = new FreeColServer(savegame, specification, null, FreeCol.getServerPort(), "mapTransformer"); - System.out.println("Started server."); + logger.info("Started server."); server.saveMapEditorGame(out, thumbnail); - System.out.println("Saved updated savegame."); + logger.info("Saved updated savegame."); server.shutdown(); - System.out.println("Shut down server."); + logger.info("Shut down server."); } catch (IOException | NullPointerException | SecurityException | XMLStreamException | FreeColException e) { - System.err.println(e); + if (logger.isLoggable(Level.SEVERE)) logger.log(Level.SEVERE, "Map conversion failed for " + filename, e); } } } } } - diff --git a/src/net/sf/freecol/tools/MergeTranslations.java b/src/net/sf/freecol/tools/MergeTranslations.java index f94dd5ca52..4e8922e917 100644 --- a/src/net/sf/freecol/tools/MergeTranslations.java +++ b/src/net/sf/freecol/tools/MergeTranslations.java @@ -31,6 +31,8 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.logging.Level; +import java.util.logging.Logger; import static net.sf.freecol.common.util.CollectionUtils.*; import net.sf.freecol.common.util.Utils; @@ -41,6 +43,8 @@ */ public class MergeTranslations { + private static final Logger logger = Logger.getLogger(MergeTranslations.class.getName()); + public static void main(String[] args) throws Exception { File sourceDirectory = new File(args[0]); @@ -61,14 +65,13 @@ public boolean accept(File dir, String name) { } }); if (sourceFiles == null) { - System.err.println("No messages files found in " - + sourceDirectory); + if (logger.isLoggable(Level.SEVERE)) logger.severe("No messages files found in " + sourceDirectory); System.exit(1); } for (String name : sourceFiles) { - System.out.println("Processing source file: " + name); + if (logger.isLoggable(Level.INFO)) logger.info("Processing source file: " + name); File sourceFile = new File(sourceDirectory, name); Map sourceProperties = readFile(sourceFile); @@ -97,7 +100,7 @@ public boolean accept(File dir, String name) { } } } else { - System.out.println("Copying " + name + " from trunk."); + if (logger.isLoggable(Level.INFO)) logger.info("Copying " + name + " from trunk."); try ( Reader in = Utils.getFileUTF8Reader(sourceFile); Writer out = Utils.getFileUTF8Writer(targetFile); @@ -126,8 +129,7 @@ private static Map readFile(File file) { line = bufferedReader.readLine(); } } catch (IOException ioe) { - System.err.println("Error reading file " + file.getName() - + ": " + ioe); + if (logger.isLoggable(Level.SEVERE)) logger.log(Level.SEVERE, "Error reading file " + file.getName(), ioe); } return result; } diff --git a/src/net/sf/freecol/tools/RiverMaker.java b/src/net/sf/freecol/tools/RiverMaker.java index 94ddf86f46..747d42525c 100644 --- a/src/net/sf/freecol/tools/RiverMaker.java +++ b/src/net/sf/freecol/tools/RiverMaker.java @@ -148,7 +148,7 @@ public static void main(String[] args) throws Exception { } - private static int[] nextBranch(int[] branches) { + private static int[] nextBranch(int... branches) { for (int index = 0; index < branches.length; index++) { if (branches[index] == 2) { branches[index] = 0; @@ -160,7 +160,7 @@ private static int[] nextBranch(int[] branches) { return branches; } - private static int branchCount(int[] branches) { + private static int branchCount(int... branches) { int result = 0; for (int branche : branches) { if (branche > 0) { @@ -170,7 +170,7 @@ private static int branchCount(int[] branches) { return result; } - private static String getName(int[] branches) { + private static String getName(int... branches) { StringBuilder sb = new StringBuilder(32); for (int branche : branches) { sb.append(branche); diff --git a/src/net/sf/freecol/tools/SaveGameValidator.java b/src/net/sf/freecol/tools/SaveGameValidator.java index a8d76d4401..f326400b9a 100644 --- a/src/net/sf/freecol/tools/SaveGameValidator.java +++ b/src/net/sf/freecol/tools/SaveGameValidator.java @@ -24,6 +24,8 @@ import java.io.InputStream; import java.util.ArrayList; import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; import javax.xml.transform.stream.StreamSource; import javax.xml.validation.Schema; @@ -42,6 +44,8 @@ */ public class SaveGameValidator { + private static final Logger logger = Logger.getLogger(SaveGameValidator.class.getName()); + public static void main(String[] args) throws Exception { SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema"); @@ -64,20 +68,20 @@ public static void main(String[] args) throws Exception { int ret = 0; for (File file : allFiles) { - //System.out.println("Processing file " + file.getPath()); + //logger.info("Processing file " + file.getPath()); try { FreeColSavegameFile mapFile = new FreeColSavegameFile(file); try (InputStream in = mapFile.getSavegameInputStream()) { saveGameValidator.validate(new StreamSource(in)); } - System.out.println("Successfully validated " + file.getName()); + if (logger.isLoggable(Level.INFO)) logger.info("Successfully validated " + file.getName()); } catch (SAXParseException e) { - System.out.println(e.getMessage() - + " at line=" + e.getLineNumber() - + " column=" + e.getColumnNumber()); + if (logger.isLoggable(Level.WARNING)) logger.warning(e.getMessage() + + " at line=" + e.getLineNumber() + + " column=" + e.getColumnNumber()); ret = Math.max(ret, 1); } catch (IOException | SAXException e) { - System.out.println("Failed to read " + file.getName()); + if (logger.isLoggable(Level.SEVERE)) logger.log(Level.SEVERE, "Failed to read " + file.getName(), e); ret = 2; } } @@ -85,4 +89,3 @@ public static void main(String[] args) throws Exception { } } - diff --git a/src/net/sf/freecol/tools/Texture2Tile.java b/src/net/sf/freecol/tools/Texture2Tile.java index a20235393e..b6d37fe543 100644 --- a/src/net/sf/freecol/tools/Texture2Tile.java +++ b/src/net/sf/freecol/tools/Texture2Tile.java @@ -24,10 +24,12 @@ import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; +import java.util.logging.Logger; import javax.imageio.ImageIO; import net.sf.freecol.common.util.ImageUtils; +import java.util.logging.Level; /** @@ -40,9 +42,10 @@ public class Texture2Tile { private static final int RESULT_WIDTH = 512; private static final int RESULT_HEIGHT = 256; + private static final Logger logger = Logger.getLogger(Texture2Tile.class.getName()); public static void main(String[] args) throws Exception { - if (args.length == 0 || args[0].equals("-h") || args[0].equals("--help")) { + if (args.length == 0 || "-h".equals(args[0]) || "--help".equals(args[0])) { printUsage(); System.exit(0); } @@ -59,15 +62,15 @@ public static void main(String[] args) throws Exception { private static void printUsage() { - System.out.println("Creates an isometric base tile image from a tiling texture."); - System.out.println(); - System.out.println("Usage: java -cp FreeCol.jar net.sf.freecol.tools.Texture2Tile IMAGE_FILE"); - System.out.println(); - System.out.println("IMAGE_FILE - A seamlessly tiling texture to be used for creating a seamlessly"); - System.out.println(" tiling isometric base tile."); - System.out.println(); - System.out.println("Two results are produced by this tool: \"generated.png\" and \"generated-rotated.png\""); - System.out.println("The best one to use depends on the texture."); + logger.info("Creates an isometric base tile image from a tiling texture."); + logger.info(""); + logger.info("Usage: java -cp FreeCol.jar net.sf.freecol.tools.Texture2Tile IMAGE_FILE"); + logger.info(""); + logger.info("IMAGE_FILE - A seamlessly tiling texture to be used for creating a seamlessly"); + logger.info(" tiling isometric base tile."); + logger.info(""); + logger.info("Two results are produced by this tool: \"generated.png\" and \"generated-rotated.png\""); + logger.info("The best one to use depends on the texture."); } @@ -86,7 +89,7 @@ private static void createRotatedResult(BufferedImage inputImage) throws IOExcep tempImage = ImageUtils.imageWithAlphaFromMask(tempImage, tileMaskImage); ImageIO.write(tempImage, "png", resultImagefile); - System.out.println("Image written to: " + resultImagefile.getAbsolutePath().toString()); + if (logger.isLoggable(Level.INFO)) logger.info("Image written to: " + resultImagefile.getAbsolutePath().toString()); } @@ -103,7 +106,7 @@ private static void createNonRotatedResult(BufferedImage inputImage) throws Exce final BufferedImage resultImage = combineQuarterTiles(imageA, imageB); ImageIO.write(resultImage, "png", resultImagefile); - System.out.println("Image written to: " + resultImagefile.getAbsolutePath().toString()); + if (logger.isLoggable(Level.INFO)) logger.info("Image written to: " + resultImagefile.getAbsolutePath().toString()); } diff --git a/src/net/sf/freecol/tools/TranslationReport.java b/src/net/sf/freecol/tools/TranslationReport.java index 8bb99b15f7..3265789154 100644 --- a/src/net/sf/freecol/tools/TranslationReport.java +++ b/src/net/sf/freecol/tools/TranslationReport.java @@ -27,6 +27,10 @@ import java.util.ArrayList; import java.util.Properties; import java.util.TreeSet; +import java.util.List; +import java.util.Set; +import java.util.logging.Logger; +import java.util.logging.Level; /** @@ -34,6 +38,8 @@ */ public class TranslationReport { + private static final Logger logger = Logger.getLogger(TranslationReport.class.getName()); + private static class LanguageStatsRecord{ String localFile = ""; int missingKeys = 0; @@ -49,7 +55,7 @@ private static class LanguageStatsRecord{ private static final boolean printSummary = true; public static void main(String[] args) throws Exception { - ArrayList statistics = new ArrayList<>(); + List statistics = new ArrayList<>(); //String dirName = "src/net/sf/freecol.common.i18n/"; String dirName = args[0]; @@ -65,7 +71,7 @@ public boolean accept(File dir, String name) { } }); if (languageFiles == null) { - System.err.println("No language files found in " + directory); + if (logger.isLoggable(Level.SEVERE)) logger.severe("No language files found in " + directory); System.exit(1); } @@ -73,7 +79,7 @@ public boolean accept(File dir, String name) { "FreeColMessages.properties"); Properties master = new Properties(); master.load(Files.newInputStream(filePath)); - //System.out.println("*** Found master property file with " + master.size() + " properties.\n"); + //logger.info("*** Found master property file with " + master.size() + " properties.\n"); Properties properties = new Properties(); for (String name : languageFiles) { @@ -82,13 +88,13 @@ public boolean accept(File dir, String name) { Path propPath = FileSystems.getDefault().getPath(args[0], name); properties.clear(); properties.load(Files.newInputStream(propPath)); - System.out.println(name.length()+8 < stars.length() ? stars.substring(0, name.length() + 8) : stars); - System.out.println("*** " + name + " ***"); - System.out.println(name.length()+8 < stars.length() ? stars.substring(0, name.length() + 8) : stars); + if (logger.isLoggable(Level.INFO)) logger.info(name.length() + 8 < stars.length() ? stars.substring(0, name.length() + 8) : stars); + if (logger.isLoggable(Level.INFO)) logger.info("*** " + name + " ***"); + if (logger.isLoggable(Level.INFO)) logger.info(name.length() + 8 < stars.length() ? stars.substring(0, name.length() + 8) : stars); - ArrayList missingKeys = new ArrayList<>(); - ArrayList missingVariables = new ArrayList<>(); - ArrayList copiedFromMaster = new ArrayList<>(); + List missingKeys = new ArrayList<>(); + List missingVariables = new ArrayList<>(); + List copiedFromMaster = new ArrayList<>(); for (Object o : master.keySet()) { String key = (String)o; @@ -114,42 +120,42 @@ public boolean accept(File dir, String name) { } if (!missingKeys.isEmpty()) { - System.out.println("** Total of " + missingKeys.size() + " properties missing:\n"); + if (logger.isLoggable(Level.INFO)) logger.info("** Total of " + missingKeys.size() + " properties missing:\n"); for (String key : sort(missingKeys)) { - System.out.println(key + "=" + master.getProperty(key)); + if (logger.isLoggable(Level.INFO)) logger.info(key + "=" + master.getProperty(key)); } lstat.missingKeys = missingKeys.size(); - System.out.println(""); + logger.info(""); } else { - System.out.println("** No properties missing.\n"); + logger.info("** No properties missing.\n"); } if (!copiedFromMaster.isEmpty()){ - System.out.println("** Total of " + copiedFromMaster.size() + " properties copied from master properties:\n"); + if (logger.isLoggable(Level.INFO)) logger.info("** Total of " + copiedFromMaster.size() + " properties copied from master properties:\n"); for (String key : sort(copiedFromMaster)) { - System.out.println(key + "=" + master.getProperty(key)); + if (logger.isLoggable(Level.INFO)) logger.info(key + "=" + master.getProperty(key)); } lstat.copiedKeys = copiedFromMaster.size(); - System.out.println(""); + logger.info(""); } else { - System.out.println("** No properties copied.\n"); + logger.info("** No properties copied.\n"); } if (!missingVariables.isEmpty()) { - System.out.println("** Total of " + missingVariables.size() + " properties with missing variables:\n"); + if (logger.isLoggable(Level.INFO)) logger.info("** Total of " + missingVariables.size() + " properties with missing variables:\n"); for (String key : sort(missingVariables)) { - System.out.println("* CORRECT: " + key + "=" + master.getProperty(key)); - System.out.println("INCORRECT: " + key + "=" + properties.getProperty(key)); + if (logger.isLoggable(Level.INFO)) logger.info("* CORRECT: " + key + "=" + master.getProperty(key)); + if (logger.isLoggable(Level.INFO)) logger.info("INCORRECT: " + key + "=" + properties.getProperty(key)); } lstat.missingVariables = missingVariables.size(); - System.out.println(""); + logger.info(""); } else { - System.out.println("** No properties with missing variables.\n"); + logger.info("** No properties with missing variables.\n"); } - ArrayList superfluousKeys = new ArrayList<>(); - ArrayList superfluousVariables = new ArrayList<>(); + List superfluousKeys = new ArrayList<>(); + List superfluousVariables = new ArrayList<>(); for (Object o : properties.keySet()) { String key = (String)o; String value = master.getProperty(key, null); @@ -165,36 +171,36 @@ public boolean accept(File dir, String name) { } if (!superfluousKeys.isEmpty()) { - System.out.println("** Total of " + superfluousKeys.size() + " superfluous properties:\n"); + if (logger.isLoggable(Level.INFO)) logger.info("** Total of " + superfluousKeys.size() + " superfluous properties:\n"); for (String key : sort(superfluousKeys)) { - System.out.println(key + "=" + properties.getProperty(key)); + if (logger.isLoggable(Level.INFO)) logger.info(key + "=" + properties.getProperty(key)); } lstat.superfluousKeys = superfluousKeys.size(); - System.out.println(""); + logger.info(""); } else { - System.out.println("** No superfluous properties.\n"); + logger.info("** No superfluous properties.\n"); } if (!superfluousVariables.isEmpty()) { - System.out.println("** Total of " + superfluousVariables.size() + + if (logger.isLoggable(Level.INFO)) logger.info("** Total of " + superfluousVariables.size() + " properties with superfluous variables:\n"); for (String key : sort(superfluousVariables)) { - System.out.println("* CORRECT: " + key + "=" + master.getProperty(key)); - System.out.println("INCORRECT: " + key + "=" + properties.getProperty(key)); + if (logger.isLoggable(Level.INFO)) logger.info("* CORRECT: " + key + "=" + master.getProperty(key)); + if (logger.isLoggable(Level.INFO)) logger.info("INCORRECT: " + key + "=" + properties.getProperty(key)); } lstat.superfluousVariables = superfluousVariables.size(); - System.out.println(""); + logger.info(""); } else { - System.out.println("** No properties with superfluous variables.\n"); + logger.info("** No properties with superfluous variables.\n"); } statistics.add(lstat); } if (printSummary){ - System.out.println(stars); - System.out.println("*** Summary of translation efforts (" + master.size() + " keys in master file) ***"); - System.out.println(stars); + logger.info(stars); + if (logger.isLoggable(Level.INFO)) logger.info("*** Summary of translation efforts (" + master.size() + " keys in master file) ***"); + logger.info(stars); for (LanguageStatsRecord stats : statistics){ StringBuilder output = new StringBuilder(); output.append(shortenName(stats.localFile)); @@ -214,7 +220,7 @@ public boolean accept(File dir, String name) { percentageDone = Math.round(percentageDone*100)/100f; output.append(percentageDone).append("% finished."); - System.out.println(output.toString()); + if (logger.isLoggable(Level.INFO)) logger.info(output.toString()); } } } @@ -223,22 +229,24 @@ public boolean accept(File dir, String name) { /** * Sets inVariable as needed */ - private static void isInVariable(ArrayList superfluousVariables, String key, String value, String propertiesValue, int lastIndex, boolean inVariable) { + private static void isInVariable(List superfluousVariables, String key, String value, String propertiesValue, int lastIndex, boolean inVariable) { + int currentIndex = lastIndex; + boolean insideVariable = inVariable; for (int index = 0; index < propertiesValue.length() - 1; index++) { char current = propertiesValue.charAt(index); if (current == '%') { - if (inVariable) { - String var = propertiesValue.substring(lastIndex, index + 1); + if (insideVariable) { + String var = propertiesValue.substring(currentIndex, index + 1); if (!value.contains(var)) { superfluousVariables.add(key); } - inVariable = false; + insideVariable = false; } else { - lastIndex = index; - inVariable = true; + currentIndex = index; + insideVariable = true; } } else if (!Character.isLetterOrDigit(current)) { - inVariable = false; + insideVariable = false; } } } @@ -270,8 +278,8 @@ private static StringBuilder prettyPrint(int number) { } - private static TreeSet sort(ArrayList missingKeys) { - TreeSet sorted = new TreeSet<>(); + private static Set sort(List missingKeys) { + Set sorted = new TreeSet<>(); sorted.addAll(missingKeys); return sorted; } diff --git a/src/overview.html b/src/overview.html index 0acde33990..412e5b52cd 100644 --- a/src/overview.html +++ b/src/overview.html @@ -1,7 +1,7 @@
This is the javadoc generated code documentation for FreeCol. -

Overview

+

Overview

The {@link net.sf.freecol main package} contains the class {@link net.sf.freecol.FreeCol} which is responsible for handling the command-line arguments and starting either @@ -18,7 +18,7 @@

Overview

in order to maintain a central list of public servers.
  -

Client/server-architecture

+

Client/server-architecture

We use a client/server-architecture. That is: a group of clients connects to the server in order to play a game. We are also using this approach even when a singleplayer game has been chosen (then there is only one @@ -43,7 +43,7 @@

Client/server-architecture


  -

The game model

+

The game model

The common package contains everything being shared between the client and the server. One of these things is the {@link net.sf.freecol.common.model game model} which is best described as diff --git a/test/lib/asm-analysis.jar b/test/lib/asm-analysis.jar new file mode 100644 index 0000000000..f4e8691b97 Binary files /dev/null and b/test/lib/asm-analysis.jar differ diff --git a/test/lib/asm-commons.jar b/test/lib/asm-commons.jar new file mode 100644 index 0000000000..75f3bad86a Binary files /dev/null and b/test/lib/asm-commons.jar differ diff --git a/test/lib/asm-tree.jar b/test/lib/asm-tree.jar new file mode 100644 index 0000000000..9fe5275876 Binary files /dev/null and b/test/lib/asm-tree.jar differ diff --git a/test/lib/asm.jar b/test/lib/asm.jar new file mode 100644 index 0000000000..cc1c2cd8e4 Binary files /dev/null and b/test/lib/asm.jar differ diff --git a/test/lib/hamcrest-core.jar b/test/lib/hamcrest-core.jar new file mode 100644 index 0000000000..9d5fe16e3d Binary files /dev/null and b/test/lib/hamcrest-core.jar differ diff --git a/test/lib/jacoco-agent.jar b/test/lib/jacoco-agent.jar new file mode 100644 index 0000000000..873ae70e14 Binary files /dev/null and b/test/lib/jacoco-agent.jar differ diff --git a/test/lib/jacoco-core.jar b/test/lib/jacoco-core.jar new file mode 100644 index 0000000000..85029df9b2 Binary files /dev/null and b/test/lib/jacoco-core.jar differ diff --git a/test/lib/jacoco-report.jar b/test/lib/jacoco-report.jar new file mode 100644 index 0000000000..d90532db24 Binary files /dev/null and b/test/lib/jacoco-report.jar differ diff --git a/test/lib/jacocoant.jar b/test/lib/jacocoant.jar new file mode 100644 index 0000000000..7514d6b7cf Binary files /dev/null and b/test/lib/jacocoant.jar differ diff --git a/test/lib/junit.jar b/test/lib/junit.jar index 3a7fc266c3..6da55d8b85 100644 Binary files a/test/lib/junit.jar and b/test/lib/junit.jar differ diff --git a/test/src/net/sf/freecol/AllTests.java b/test/src/net/sf/freecol/AllTests.java index a205dae72e..3071062abc 100644 --- a/test/src/net/sf/freecol/AllTests.java +++ b/test/src/net/sf/freecol/AllTests.java @@ -20,6 +20,9 @@ package net.sf.freecol; import java.util.Locale; +import java.util.logging.Level; +import java.util.logging.LogManager; +import java.util.logging.Logger; import junit.extensions.TestSetup; import junit.framework.Test; @@ -32,6 +35,7 @@ public class AllTests { public static Test suite() { + configureTestLogging(); TestSuite suite = new TestSuite("Test for net.sf.freecol"); // $JUnit-BEGIN$ @@ -46,10 +50,16 @@ public static Test suite() { TestSetup wrapper = new TestSetup(suite) { public void setUp() { Locale.setDefault(Locale.US); + configureTestLogging(); } }; return wrapper; } + private static void configureTestLogging() { + LogManager.getLogManager().reset(); + Logger rootLogger = Logger.getLogger(""); + rootLogger.setLevel(Level.SEVERE); + } } diff --git a/test/src/net/sf/freecol/common/AllTests.java b/test/src/net/sf/freecol/common/AllTests.java index 88926f83c5..3019cb98a7 100644 --- a/test/src/net/sf/freecol/common/AllTests.java +++ b/test/src/net/sf/freecol/common/AllTests.java @@ -29,6 +29,7 @@ public static Test suite() { //$JUnit-BEGIN$ suite.addTest(net.sf.freecol.common.i18n.AllTests.suite()); suite.addTest(net.sf.freecol.common.io.AllTests.suite()); + suite.addTest(net.sf.freecol.common.networking.AllTests.suite()); suite.addTest(net.sf.freecol.common.option.AllTests.suite()); suite.addTest(net.sf.freecol.common.model.AllTests.suite()); suite.addTest(net.sf.freecol.common.utils.AllTests.suite()); diff --git a/test/src/net/sf/freecol/common/model/ColonyTest.java b/test/src/net/sf/freecol/common/model/ColonyTest.java index 5fc9217bd3..96bc85dc58 100644 --- a/test/src/net/sf/freecol/common/model/ColonyTest.java +++ b/test/src/net/sf/freecol/common/model/ColonyTest.java @@ -23,6 +23,7 @@ import static net.sf.freecol.common.util.CollectionUtils.first; import net.sf.freecol.common.model.Player.NoClaimReason; +import net.sf.freecol.server.model.ServerBuilding; import net.sf.freecol.server.model.ServerPlayer; import net.sf.freecol.server.model.ServerUnit; import net.sf.freecol.util.test.FreeColTestCase; @@ -121,6 +122,43 @@ public void testBuildQueueAcceptsUnitDoubles() { 3, colony.getBuildQueue().size()); } + public void testClothProductionRequiresCotton() { + Game game = getGame(); + game.changeMap(getTestMap(true)); + + Colony colony = createStandardColony(); + Building weaversHouse = colony.getBuilding(weaversHouseType); + if (weaversHouse == null) { + weaversHouse = new ServerBuilding(game, colony, weaversHouseType); + colony.addBuilding(weaversHouse); + } + clearWorkLocation(weaversHouse); + + Unit weaver = new ServerUnit(game, colony.getTile(), + colony.getOwner(), masterWeaverType); + weaver.setLocation(weaversHouse); + + colony.addGoods(cottonGoodsType, 50); + colony.invalidateCache(); + ProductionInfo withCottonInfo = colony.getProductionInfo(weaversHouse); + int withCottonDeficit = AbstractGoods.getCount(cottonGoodsType, + withCottonInfo.getConsumptionDeficit()); + int withCotton = colony.getNetProductionOf(clothGoodsType); + assertEquals("Cotton deficit should be zero when cotton is available", + 0, withCottonDeficit); + assertTrue("Cloth production should resume with cotton", + withCotton > 0); + + colony.removeGoods(cottonGoodsType, + colony.getGoodsCount(cottonGoodsType)); + colony.invalidateCache(); + ProductionInfo noCottonInfo = colony.getProductionInfo(weaversHouse); + int noCottonDeficit = AbstractGoods.getCount(cottonGoodsType, + noCottonInfo.getConsumptionDeficit()); + assertTrue("Cotton deficit should be reported when input is missing", + noCottonDeficit > 0); + } + public void testOccupationWithFood() { Game game = getGame(); game.changeMap(getTestMap(true)); diff --git a/test/src/net/sf/freecol/common/model/PathfindingTest.java b/test/src/net/sf/freecol/common/model/PathfindingTest.java index 69233cf737..ff1c5064ae 100644 --- a/test/src/net/sf/freecol/common/model/PathfindingTest.java +++ b/test/src/net/sf/freecol/common/model/PathfindingTest.java @@ -31,6 +31,7 @@ public class PathfindingTest extends FreeColTestCase { private final TileType plainsType = spec().getTileType("model.tile.plains"); + private final TileType oceanType = spec().getTileType("model.tile.ocean"); private final UnitType colonistType = spec().getUnitType("model.unit.freeColonist"); @@ -131,7 +132,30 @@ public boolean check(Unit u, PathNode path) { gd = GoalDeciders.getComposedGoalDecider(false, nativeGD, colonyGD); path = unit.search(unitTile, gd, null, 1, null); assertNotNull(path); - assertEquals("Composed-OR GoalDecider should find colony", colonyTile, + Tile found = path.getLastNode().getTile(); + assertTrue("Composed-OR GoalDecider should find colony or natives", + found == colonyTile || found == nativeTile); + } + + public void testPathAvoidsOceanBlock() { + final Game game = getStandardGame(); + final Map map = getTestMap(plainsType, true); + game.changeMap(map); + + final Player dutch = game.getPlayerByNationId("model.nation.dutch"); + final Tile start = map.getTile(3, 3); + final Tile target = map.getTile(5, 3); + final Tile blocked = map.getTile(4, 3); + blocked.setType(oceanType); + + final Unit unit = new ServerUnit(game, start, dutch, colonistType); + final GoalDecider gd = GoalDeciders.getLocationGoalDecider(target); + final PathNode path = unit.search(start, gd, null, 1, null); + + assertNotNull("Path should be found around ocean", path); + assertEquals("Path should reach target", target, path.getLastNode().getTile()); + assertTrue("Path should detour around ocean", + path.getLength() > 3); } } diff --git a/test/src/net/sf/freecol/common/model/UnitTest.java b/test/src/net/sf/freecol/common/model/UnitTest.java index 85e95fe2a1..c6470b6025 100644 --- a/test/src/net/sf/freecol/common/model/UnitTest.java +++ b/test/src/net/sf/freecol/common/model/UnitTest.java @@ -542,6 +542,41 @@ public void testCopy() { assertEquals(merchantman.getUnitList().get(0).getId(), other.getUnitList().get(0).getId()); } + + public void testChangeRoleClearsExperienceOnIncompatibleRole() { + Game game = getStandardGame(); + Map map = getTestMap(plains, true); + game.changeMap(map); + + Player dutch = game.getPlayerByNationId("model.nation.dutch"); + Tile tile = map.getTile(6, 8); + Unit colonist = new ServerUnit(game, tile, dutch, colonistType); + colonist.setRole(soldierRole); + colonist.setExperience(10); + assertTrue("Setup error, experience should be set", + colonist.getExperience() > 0); + + colonist.changeRole(scoutRole, 1); + assertEquals("Experience should reset when changing to incompatible role", + 0, colonist.getExperience()); + } + + public void testChangeRoleCountResetsToDefaultRole() { + Game game = getStandardGame(); + Map map = getTestMap(plains, true); + game.changeMap(map); + + Player dutch = game.getPlayerByNationId("model.nation.dutch"); + Tile tile = map.getTile(6, 8); + Unit colonist = new ServerUnit(game, tile, dutch, colonistType); + colonist.changeRole(soldierRole, 1); + assertEquals(1, colonist.getRoleCount()); + + assertTrue("Role count should reach zero", colonist.changeRoleCount(-1)); + assertEquals("Role count should be zero", 0, colonist.getRoleCount()); + assertEquals("Role should reset to default", + spec().getDefaultRole(), colonist.getRole()); + } public void testDefaultRole() { for (UnitType type : spec().getUnitTypeList()) { diff --git a/test/src/net/sf/freecol/common/networking/AllTests.java b/test/src/net/sf/freecol/common/networking/AllTests.java new file mode 100644 index 0000000000..451a063fba --- /dev/null +++ b/test/src/net/sf/freecol/common/networking/AllTests.java @@ -0,0 +1,34 @@ +/** + * Copyright (C) 2002-2024 The FreeCol Team + * + * This file is part of FreeCol. + * + * FreeCol is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * FreeCol is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with FreeCol. If not, see . + */ + +package net.sf.freecol.common.networking; + +import junit.framework.Test; +import junit.framework.TestSuite; + +public class AllTests { + + public static Test suite() { + TestSuite suite = new TestSuite("Test for net.sf.freecol.common.networking"); + //$JUnit-BEGIN$ + suite.addTestSuite(MessageRoundTripTest.class); + //$JUnit-END$ + return suite; + } +} diff --git a/test/src/net/sf/freecol/common/networking/MessageRoundTripTest.java b/test/src/net/sf/freecol/common/networking/MessageRoundTripTest.java new file mode 100644 index 0000000000..5154a00c06 --- /dev/null +++ b/test/src/net/sf/freecol/common/networking/MessageRoundTripTest.java @@ -0,0 +1,96 @@ +/** + * Copyright (C) 2002-2024 The FreeCol Team + * + * This file is part of FreeCol. + * + * FreeCol is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * FreeCol is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with FreeCol. If not, see . + */ + +package net.sf.freecol.common.networking; + +import java.io.StringReader; +import java.io.StringWriter; +import java.util.HashMap; +import java.util.Map; + +import net.sf.freecol.common.io.FreeColXMLReader; +import net.sf.freecol.common.io.FreeColXMLWriter; +import net.sf.freecol.common.model.Direction; +import net.sf.freecol.common.model.Game; +import net.sf.freecol.common.model.Player; +import net.sf.freecol.common.model.Tile; +import net.sf.freecol.common.model.TileType; +import net.sf.freecol.common.model.Unit; +import net.sf.freecol.common.model.UnitType; +import net.sf.freecol.server.model.ServerUnit; +import net.sf.freecol.util.test.FreeColTestCase; + + +public class MessageRoundTripTest extends FreeColTestCase { + + private final TileType plainsType = spec().getTileType("model.tile.plains"); + private final UnitType colonistType = spec().getUnitType("model.unit.freeColonist"); + + private Message roundTrip(Game game, Message message) throws Exception { + StringWriter out = new StringWriter(); + try (FreeColXMLWriter xw = new FreeColXMLWriter(out)) { + message.toXML(xw); + xw.flush(); + } + String xml = out.toString(); + try (FreeColXMLReader xr = new FreeColXMLReader(new StringReader(xml))) { + xr.nextTag(); + return Message.read(game, xr); + } + } + + private void assertRoundTrip(Game game, Message message) throws Exception { + Map expected = new HashMap<>(message.getStringAttributeMap()); + Message parsed = roundTrip(game, message); + assertEquals(message.getType(), parsed.getType()); + assertEquals(expected, parsed.getStringAttributeMap()); + } + + public void testMoveMessageRoundTrip() throws Exception { + Game game = getStandardGame(); + net.sf.freecol.common.model.Map map = getTestMap(plainsType, true); + game.changeMap(map); + + Player dutch = game.getPlayerByNationId("model.nation.dutch"); + Tile tile = map.getTile(6, 8); + Unit unit = new ServerUnit(game, tile, dutch, colonistType); + + Message message = new MoveMessage(unit, Direction.NE); + assertRoundTrip(game, message); + } + + public void testBuildColonyMessageRoundTrip() throws Exception { + Game game = getStandardGame(); + net.sf.freecol.common.model.Map map = getTestMap(plainsType, true); + game.changeMap(map); + + Player dutch = game.getPlayerByNationId("model.nation.dutch"); + Tile tile = map.getTile(6, 8); + Unit unit = new ServerUnit(game, tile, dutch, colonistType); + + Message message = new BuildColonyMessage("New Amsterdam", unit); + assertRoundTrip(game, message); + } + + public void testEndTurnMessageRoundTrip() throws Exception { + Game game = getStandardGame(); + Message message = new EndTurnMessage(); + assertRoundTrip(game, message); + } +} diff --git a/test/src/net/sf/freecol/common/utils/UtilsTest.java b/test/src/net/sf/freecol/common/utils/UtilsTest.java index ba0588c84e..6fd599fbca 100644 --- a/test/src/net/sf/freecol/common/utils/UtilsTest.java +++ b/test/src/net/sf/freecol/common/utils/UtilsTest.java @@ -20,7 +20,9 @@ package net.sf.freecol.common.utils; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import java.util.Map; import net.sf.freecol.common.util.CollectionUtils; @@ -76,4 +78,39 @@ public void testComparator() { o.sort(CollectionUtils.descendingListLengthComparator); assertEquals(o.get(0), o3); } + + public void testAsMapOddLength() { + Map map = CollectionUtils.asMap(1, 2, 3); + assertEquals(1, map.size()); + assertEquals(Integer.valueOf(2), map.get(1)); + assertFalse(map.containsKey(3)); + } + + public void testAppendToMapListNoDuplicates() { + Map> map = new java.util.HashMap<>(); + CollectionUtils.appendToMapList(map, "a", 1); + CollectionUtils.appendToMapList(map, "a", 1); + CollectionUtils.appendToMapList(map, "a", 2); + assertEquals(Arrays.asList(1, 2), map.get("a")); + } + + public void testAccumulateToMap() { + Map map = new java.util.HashMap<>(); + CollectionUtils.accumulateToMap(map, "a", 2, Integer::sum); + CollectionUtils.accumulateToMap(map, "a", 3, Integer::sum); + assertEquals(Integer.valueOf(5), map.get("a")); + } + + public void testAllSame() { + assertTrue(CollectionUtils.allSame(Arrays.asList("x", "x", "x"))); + assertFalse(CollectionUtils.allSame(Arrays.asList("x", "y"))); + } + + public void testRotateList() { + List list = makeList(1, 2, 3, 4, 5); + CollectionUtils.rotate(list, 2); + assertEquals(makeList(3, 4, 5, 1, 2), list); + CollectionUtils.rotate(list, -2); + assertEquals(makeList(1, 2, 3, 4, 5), list); + } }