23 package com.realtime.crossfire.jxclient.main;
112 import java.io.FileOutputStream;
113 import java.io.IOException;
114 import java.io.OutputStreamWriter;
115 import java.io.Writer;
116 import java.lang.reflect.InvocationTargetException;
117 import java.nio.charset.StandardCharsets;
118 import java.nio.file.Path;
119 import java.util.MissingResourceException;
120 import java.util.ResourceBundle;
121 import java.util.concurrent.atomic.AtomicReference;
122 import javax.swing.SwingUtilities;
123 import org.jetbrains.annotations.NotNull;
124 import org.jetbrains.annotations.Nullable;
142 "http://crossfire.real-time.com/metaserver2/meta_client.php",
143 "http://metaserver.eu.cross-fire.org/meta_client.php",
144 "http://metaserver.us.cross-fire.org/meta_client.php",
151 public static void main(@NotNull
final String @NotNull [] args) {
152 Thread.currentThread().setName(
"JXClient:Main");
154 System.out.println(
"JXClient "+buildNumber+
" - Crossfire Java Client");
155 System.out.println(
"Copyright (C) 2005-2008 Yann \"Lauwenmark\" Chachkoff");
156 System.out.println(
"Copyright (C) 2006-2017,2019-2023 Andreas Kirschbaum");
157 System.out.println(
"Copyright (C) 2010-2012,2014-2018,2020-2023 Nicolas Weeger");
158 System.out.println(
"This software is placed under the GPL License");
172 return ResourceBundle.getBundle(
"build").getString(
"build.number");
173 }
catch (
final MissingResourceException ignored) {
185 return ResourceBundle.getBundle(
"build").getString(
"sounds.credits");
186 }
catch (
final MissingResourceException ignored) {
199 try (Writer debugProtocolOutputStreamWriter =
openDebugStream(options.getDebugProtocolFilename())) {
200 try (Writer debugKeyboardOutputStreamWriter =
openDebugStream(options.getDebugKeyboardFilename())) {
201 try (Writer debugMouseOutputStreamWriter =
openDebugStream(options.getDebugMouseFilename())) {
202 try (Writer debugScreenOutputStreamWriter =
openDebugStream(options.getDebugScreenFilename())) {
203 try (Writer debugSoundOutputStreamWriter =
openDebugStream(options.getDebugSoundFilename())) {
205 settings.
remove(
"resolution");
207 settings.
remove(
"height");
226 metaserverProcessor.
start();
228 soundManager.
start();
232 throw new AssertionError(ex);
237 throw new AssertionError(ex);
264 final AtomicReference<JXCWindow> window =
new AtomicReference<>();
265 final Path keybindingsFileVersion2;
268 }
catch (
final IOException ex) {
269 System.err.println(
"Cannot read keybindings file: "+ex.getMessage());
273 final Path keybindingsFileVersion1;
276 }
catch (
final IOException ex) {
277 System.err.println(
"Cannot read keybindings file: "+ex.getMessage());
281 SwingUtilities.invokeAndWait(() -> {
282 final Pickup characterPickup;
284 characterPickup =
new Pickup(commandQueue, optionManager);
286 throw new AssertionError(ex);
297 commandCallback.
init(guiManager);
318 optionManager.
addOption(
"translucent_dialogs_enabled",
"Whether translucent dialog backgrounds are enabled.", translucentDialogsCheckBoxOption);
320 throw new AssertionError(ex);
324 optionManager.
addOption(
"show_timestamp_messages_enabled",
"Whether timestamps in the message window are enabled.", showTimestampMessagesCheckBoxOption);
326 throw new AssertionError(ex);
330 optionManager.
addOption(
"show_sent_commands_enabled",
"Whether commands sent to the server are shown in the messages dialog.", showSentCommandsCheckBoxOption);
332 throw new AssertionError(ex);
335 final JXCSkinLoader jxcSkinLoader =
new JXCSkinLoader(model, inventoryView, floorView, spellsView, spellSkillsView, facesManager, mapUpdaterState, defaultKeyBindings, optionManager, options.getTileSize(), keybindingsManager, questsView, commandHistoryFactory, knowledgeView, knowledgeTypesView, options.isAvoidCopyArea(), guiManager, guiFactory, pendingDirections,
getSoundsCredits(), options.getFontScaleFactor());
336 final SkinLoader skinLoader =
new SkinLoader(commandCallback, metaserverModel, options.getResolution(), macros, windowRenderer, server, model.
getGuiStateManager(), tooltipManager, commandQueue, jxcSkinLoader, commandExecutor, shortcuts, characterModel, model.
getSmoothFaces(), guiFactory);
341 final KeyHandler keyHandler =
new KeyHandler(debugKeyboardOutputStreamWriter, keybindingsManager, commandQueue, windowRenderer, defaultKeyHandler);
343 final String skinName = options.getSkin();
346 skin = skinLoader.
loadSkin(skinName);
349 System.err.println(
"cannot load skin "+skinName+
": "+ex.getMessage());
353 System.err.println(
"cannot load skin "+skinName+
": "+ex.getMessage()+
", trying default skin");
358 System.err.println(
"cannot load default skin "+
Options.
DEFAULT_SKIN+
": "+ex2.getMessage());
360 throw new AssertionError(ex2);
364 window.set(
new JXCWindow(exiter, server, optionManager, model.
getGuiStateManager(), windowRenderer, commandQueue, guiManager, keyHandler, characterModel, connection, options.getResolution(), options.isFullScreen(), skin));
366 final String serverInfo = options.getServer();
367 if (serverInfo ==
null) {
374 SwingUtilities.invokeAndWait(window.get()::term);
384 }
catch (
final InterruptedException|InvocationTargetException|
387 ex.printStackTrace();
389 throw new AssertionError(ex);
402 if (filename ==
null) {
406 Writer writer =
null;
408 final FileOutputStream outputStream =
new FileOutputStream(filename);
411 writer =
new OutputStreamWriter(outputStream, StandardCharsets.UTF_8);
413 if (writer ==
null) {
414 outputStream.close();
417 }
catch (
final IOException ex) {
418 System.err.println(filename+
": cannot create output file: "+ex.getMessage());