diff --git a/INSTALL.txt b/INSTALL.txt
index 15a962df2..adbbc5ad5 100644
--- a/INSTALL.txt
+++ b/INSTALL.txt
@@ -1,10 +1,17 @@
I2P source installation instructions
+Prerequisites to build from source:
+ Java SDK (preferably Sun) 1.5.0 or higher (1.6 recommended)
+ Apache Ant 1.7.0 or higher
+ Optional, For multilanguage support: The xgettext, msgfmt, and msgmerge tools installed
+ from the GNU gettext package http://www.gnu.org/software/gettext/
+
To build and install I2P from source, you must first build
and package up the appropriate installer by running:
ant pkg
+
This will produce a few key files:
* install.jar: the GUI and console installer
* i2pinstall.exe: the GUI and console installer wrapped for cross-platform execution
@@ -18,9 +25,6 @@ Or run the GUI installer:
Or move the update file into an existing installation directory and restart.
-You will need to have ant installed from http://ant.apache.org/
-(1.7.0 or newer)
-
Supported JVMs:
Windows: Latest available from http://java.sun.com/ (1.5+ supported)
Linux: Latest available from http://java.sun.com/ (1.5+ supported)
diff --git a/README.txt b/README.txt
index 3aa2141bb..c5ddc12bd 100644
--- a/README.txt
+++ b/README.txt
@@ -1,11 +1,13 @@
Prerequisites to build from source:
Java SDK (preferably Sun) 1.5.0 or higher (1.6 recommended)
Apache Ant 1.7.0 or higher
+ Optional, For multilanguage support: The xgettext, msgfmt, and msgmerge tools installed
+ from the GNU gettext package http://www.gnu.org/software/gettext/
To build:
ant pkg
Run 'ant' with no arguments to see other build options.
- See http://www.i2p2.de/download.html for installation instructions.
+ See INSTALL.txt or http://www.i2p2.de/download.html for installation instructions.
Documentation:
http://www.i2p2.de/
diff --git a/apps/BOB/build.xml b/apps/BOB/build.xml
index 0d2a66eaa..aa22e12ee 100644
--- a/apps/BOB/build.xml
+++ b/apps/BOB/build.xml
@@ -71,4 +71,44 @@
nbproject/build-impl.xml file.
-->
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/BOB/nbproject/private/private.properties b/apps/BOB/nbproject/private/private.properties
index 416ecb6b1..9010904cd 100644
--- a/apps/BOB/nbproject/private/private.properties
+++ b/apps/BOB/nbproject/private/private.properties
@@ -3,5 +3,6 @@ do.depend=false
do.jar=true
javac.debug=true
javadoc.preview=true
+jaxbwiz.endorsed.dirs=/usr/local/netbeans-6.8/ide12/modules/ext/jaxb/api
jaxws.endorsed.dir=/usr/local/netbeans-6.5/java2/modules/ext/jaxws21/api:/usr/local/netbeans-6.5/ide10/modules/ext/jaxb/api
user.properties.file=/root/.netbeans/6.5/build.properties
diff --git a/apps/BOB/nbproject/private/private.xml b/apps/BOB/nbproject/private/private.xml
index 653e554c3..c1f155a78 100644
--- a/apps/BOB/nbproject/private/private.xml
+++ b/apps/BOB/nbproject/private/private.xml
@@ -1,7 +1,4 @@
-
- file:/usblv/NetBeansProjects/i2p.i2p/apps/BOB/src/net/i2p/BOB/TCPio.java
-
diff --git a/apps/BOB/nbproject/project.properties b/apps/BOB/nbproject/project.properties
index 9eeffd29f..44a617388 100644
--- a/apps/BOB/nbproject/project.properties
+++ b/apps/BOB/nbproject/project.properties
@@ -1,5 +1,6 @@
+application.homepage=http://bob.i2p/
application.title=BOB
-application.vendor=root
+application.vendor=Sponge
auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.expand-tabs=false
auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.indent-shift-width=8
auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.spaces-per-tab=8
@@ -11,6 +12,7 @@ build.classes.excludes=**/*.java,**/*.form
# This directory is removed when the project is cleaned:
build.dir=build
build.generated.dir=${build.dir}/generated
+build.generated.sources.dir=${build.dir}/generated-sources
# Only compile against the classpath explicitly listed here:
build.sysclasspath=ignore
build.test.classes.dir=${build.dir}/test/classes
@@ -23,6 +25,7 @@ debug.test.classpath=\
dist.dir=dist
dist.jar=${dist.dir}/BOB.jar
dist.javadoc.dir=${dist.dir}/javadoc
+endorsed.classpath=
excludes=
file.reference.build-javadoc=../../i2p.i2p/build/javadoc
file.reference.i2p.jar=../../core/java/build/i2p.jar
@@ -33,7 +36,7 @@ file.reference.router.jar=../../router/java/build/router.jar
file.reference.streaming.jar=../streaming/java/build/streaming.jar
file.reference.wrapper.jar=../../installer/lib/wrapper/linux/wrapper.jar
includes=**
-jar.compress=false
+jar.compress=true
javac.classpath=\
${file.reference.router.jar}:\
${file.reference.i2ptunnel.jar}:\
@@ -63,8 +66,9 @@ javadoc.splitindex=true
javadoc.use=true
javadoc.version=false
javadoc.windowtitle=
+jaxbwiz.endorsed.dirs="${netbeans.home}/../ide12/modules/ext/jaxb/api"
jnlp.codebase.type=local
-jnlp.codebase.url=file:/root/NetBeansProjects/i2p.i2p/apps/BOB/dist/
+jnlp.codebase.url=file:/usblv/NetBeansProjects/i2p.i2p/apps/BOB/dist
jnlp.descriptor=application
jnlp.enabled=false
jnlp.offline-allowed=false
diff --git a/apps/BOB/src/net/i2p/BOB/COPYING b/apps/BOB/src/net/i2p/BOB/license-WTFPL.txt
similarity index 100%
rename from apps/BOB/src/net/i2p/BOB/COPYING
rename to apps/BOB/src/net/i2p/BOB/license-WTFPL.txt
diff --git a/apps/i2psnark/java/bundle-messages.sh b/apps/i2psnark/java/bundle-messages.sh
index ad8c0ab84..01aa5b1c7 100755
--- a/apps/i2psnark/java/bundle-messages.sh
+++ b/apps/i2psnark/java/bundle-messages.sh
@@ -73,7 +73,7 @@ do
echo "Generating ${CLASS}_$LG ResourceBundle..."
# convert to class files in build/obj
- msgfmt --java -r $CLASS -l $LG -d build/obj $i
+ msgfmt --java --statistics -r $CLASS -l $LG -d build/obj $i
if [ $? -ne 0 ]
then
echo 'Warning - msgfmt failed, not updating translations'
diff --git a/apps/i2psnark/java/src/org/klomp/snark/TrackerClient.java b/apps/i2psnark/java/src/org/klomp/snark/TrackerClient.java
index 46952d14a..b9c6ec252 100644
--- a/apps/i2psnark/java/src/org/klomp/snark/TrackerClient.java
+++ b/apps/i2psnark/java/src/org/klomp/snark/TrackerClient.java
@@ -370,8 +370,13 @@ public class TrackerClient extends I2PAppThread
}
/**
- * Very lazy byte[] to URL encoder. Just encodes everything, even
- * "normal" chars.
+ * Very lazy byte[] to URL encoder. Just encodes almost everything, even
+ * some "normal" chars.
+ * By not encoding about 1/4 of the chars, we make random data like hashes about 16% smaller.
+ *
+ * RFC1738: 0-9a-zA-Z$-_.+!*'(),
+ * Us: 0-9a-zA-Z
+ *
*/
public static String urlencode(byte[] bs)
{
@@ -379,10 +384,16 @@ public class TrackerClient extends I2PAppThread
for (int i = 0; i < bs.length; i++)
{
int c = bs[i] & 0xFF;
- sb.append('%');
- if (c < 16)
- sb.append('0');
- sb.append(Integer.toHexString(c));
+ if ((c >= '0' && c <= '9') ||
+ (c >= 'A' && c <= 'Z') ||
+ (c >= 'a' && c <= 'z')) {
+ sb.append((char)c);
+ } else {
+ sb.append('%');
+ if (c < 16)
+ sb.append('0');
+ sb.append(Integer.toHexString(c));
+ }
}
return sb.toString();
diff --git a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java
index 305a9eb06..2fbf10462 100644
--- a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java
+++ b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java
@@ -185,7 +185,7 @@ public class I2PSnarkServlet extends HttpServlet {
out.write("
\n" +
"
");
out.write(_("Totals"));
- out.write(" {");
+ out.write(" (");
out.write(_("{0} torrents", snarks.size()));
out.write(", ");
out.write(DataHelper.formatSize(stats[5]) + "B, ");
@@ -216,7 +216,7 @@ public class I2PSnarkServlet extends HttpServlet {
String action = req.getParameter("action");
if (action == null) {
// noop
- } else if (_("Add torrent").equals(action)) {
+ } else if ("Add".equals(action)) {
String newFile = req.getParameter("newFile");
String newURL = req.getParameter("newURL");
// NOTE - newFile currently disabled in HTML form - see below
@@ -260,7 +260,7 @@ public class I2PSnarkServlet extends HttpServlet {
} else {
// no file or URL specified
}
- } else if (_("Stop").equals(action)) {
+ } else if ("Stop".equals(action)) {
String torrent = req.getParameter("torrent");
if (torrent != null) {
byte infoHash[] = Base64.decode(torrent);
@@ -275,7 +275,7 @@ public class I2PSnarkServlet extends HttpServlet {
}
}
}
- } else if (_("Start").equals(action)) {
+ } else if ("Start".equals(action)) {
String torrent = req.getParameter("torrent");
if (torrent != null) {
byte infoHash[] = Base64.decode(torrent);
@@ -357,7 +357,7 @@ public class I2PSnarkServlet extends HttpServlet {
}
}
}
- } else if (_("Save configuration").equals(action)) {
+ } else if ("Save".equals(action)) {
String dataDir = req.getParameter("dataDir");
boolean autoStart = req.getParameter("autoStart") != null;
String seedPct = req.getParameter("seedPct");
@@ -371,7 +371,7 @@ public class I2PSnarkServlet extends HttpServlet {
boolean useOpenTrackers = req.getParameter("useOpenTrackers") != null;
String openTrackers = req.getParameter("openTrackers");
_manager.updateConfig(dataDir, autoStart, seedPct, eepHost, eepPort, i2cpHost, i2cpPort, i2cpOpts, upLimit, upBW, useOpenTrackers, openTrackers);
- } else if (_("Create torrent").equals(action)) {
+ } else if ("Create".equals(action)) {
String baseData = req.getParameter("baseFile");
if (baseData != null && baseData.trim().length() > 0) {
File baseFile = new File(_manager.getDataDir(), baseData);
@@ -518,7 +518,7 @@ public class I2PSnarkServlet extends HttpServlet {
curPeers + '/' + knownPeers +
" " + _("peers") + ")";
else if (isRunning)
- statusString = _("Seeding") + " (" + curPeers + "/" + knownPeers + ' ' + ("peers") + ')';
+ statusString = _("Seeding") + " (" + curPeers + "/" + knownPeers + ' ' + _("peers") + ')';
else
statusString = _("Complete");
} else {
@@ -695,9 +695,9 @@ public class I2PSnarkServlet extends HttpServlet {
} else {
out.write("");
out.write(formatSize(peer.getDownloadRate()) + "ps");
}
@@ -711,9 +711,9 @@ public class I2PSnarkServlet extends HttpServlet {
} else {
out.write("");
out.write(formatSize(peer.getUploadRate()) + "ps");
}
@@ -738,6 +738,7 @@ public class I2PSnarkServlet extends HttpServlet {
// *not* enctype="multipart/form-data", so that the input type=file sends the filename, not the file
out.write("
\n");
out.write("
\n");
out.write("\n");
+ out.write("\n");
out.write("");
out.write(_("Configuration"));
out.write(" \n");
@@ -912,7 +915,7 @@ public class I2PSnarkServlet extends HttpServlet {
out.write("
\n");
+ out.write("\" name=\"foo\" >\n");
out.write("\n");
out.write("");
}
@@ -970,6 +973,7 @@ private static class FetchAndAdd implements Runnable {
in = new FileInputStream(file);
MetaInfo info = new MetaInfo(in);
String name = info.getName();
+ name = DataHelper.stripHTML(name); // XSS
name = name.replace('/', '_');
name = name.replace('\\', '_');
name = name.replace('&', '+');
diff --git a/apps/i2psnark/locale/messages_ru.po b/apps/i2psnark/locale/messages_ru.po
new file mode 100644
index 000000000..3e7ab41b1
--- /dev/null
+++ b/apps/i2psnark/locale/messages_ru.po
@@ -0,0 +1,648 @@
+# I2P
+# Copyright (C) 2009 The I2P Project
+# This file is distributed under the same license as the i2psnark package.
+# To contribute translations, see http://www.i2p2.de/newdevelopers
+# foo , 2009.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: I2P i2psnark\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-12-14 03:19+0000\n"
+"PO-Revision-Date: 2009-12-20 07:03+0000\n"
+"Last-Translator: 4get \n"
+"Language-Team: foo \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Poedit-Language: Russian\n"
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:84
+#, java-format
+msgid "Adding torrents in {0} minutes"
+msgstr "Торренты будут подгружены через {0} минут(ы)"
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:241
+#, java-format
+msgid "Total uploaders limit changed to {0}"
+msgstr "Новое значение лимита количества слотов отдачи: {0}"
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:243
+#, java-format
+msgid "Minimum total uploaders limit is {0}"
+msgstr "Минимально допустимое значение для количества слотов: {0}"
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:255
+#, java-format
+msgid "Up BW limit changed to {0}KBps"
+msgstr "Новое значение лимита скорости отдачи: {0} KBps"
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:257
+#, java-format
+msgid "Minimum up bandwidth limit is {0}KBps"
+msgstr "Минимально допустимое значение для лимита скорости отдачи: {0} KBps"
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:301
+msgid "Cannot change the I2CP settings while torrents are active"
+msgstr "Невозможно изменить настройки I2CP пока есть активные торренты"
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:307
+msgid "Disconnecting old I2CP destination"
+msgstr "Рассоединяемся по старому адресу I2CP"
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:311
+#, java-format
+msgid "I2CP settings changed to {0}"
+msgstr "Новые параметры I2CP: {0}"
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:315
+msgid "Unable to connect with the new settings, reverting to the old I2CP settings"
+msgstr "Не удалось соединиться с использованием новых настроек I2CP, возвращаемся к старым настройкам"
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:319
+msgid "Unable to reconnect with the old settings!"
+msgstr "Не удалось пересоединиться с использованием старых настроек I2CP!"
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:321
+msgid "Reconnected on the new I2CP destination"
+msgstr "Пересоединились по новому адресу I2CP"
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:332
+#, java-format
+msgid "I2CP listener restarted for \"{0}\""
+msgstr "I2CP-приёмник перезапущен для \"{0}\""
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:343
+msgid "Enabled autostart"
+msgstr "Автостарт включен"
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:345
+msgid "Disabled autostart"
+msgstr "Автостарт выключен"
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:351
+msgid "Enabled open trackers - torrent restart required to take effect."
+msgstr "Включено использование открытых трекеров. Требуется перезапуск торрента, чтобы изменения вступили в силу."
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:353
+msgid "Disabled open trackers - torrent restart required to take effect."
+msgstr "Отключено использование открытых трекеров. Требуется перезапуск торрента, чтобы изменения вступили в силу."
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:360
+msgid "Open Tracker list changed - torrent restart required to take effect."
+msgstr "Изменен список открытых трекеров. Требуется перезапуск торрента, чтобы изменения вступили в силу."
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:367
+msgid "Configuration unchanged."
+msgstr "Настройки не изменились."
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:377
+#, java-format
+msgid "Unable to save the config to {0}"
+msgstr "Не удалось сохранить настройки в {0}"
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:395
+msgid "Connecting to I2P"
+msgstr "Устанавливается соединение с I2P"
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:398
+msgid "Error connecting to I2P - check your I2CP settings!"
+msgstr "Ошибка соединения с I2P, проверьте настройки I2CP!"
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:407
+#, java-format
+msgid "Error: Could not add the torrent {0}"
+msgstr "Ошибка: Не удалось добавить торрент {0}"
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:446
+#, java-format
+msgid "Torrent in \"{0}\" is invalid"
+msgstr "Торрент в \"{0}\" некорректен"
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:461
+#, java-format
+msgid "Torrent added and started: \"{0}\""
+msgstr "Торрент добавлен и запущен: \"{0}\""
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:463
+#, java-format
+msgid "Torrent added: \"{0}\""
+msgstr "Торрент добавлен: \"{0}\""
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:559
+#, java-format
+msgid "Non-i2p tracker in \"{0}\", deleting it from our list of trackers!"
+msgstr "Обнаружен не-I2P трекер в торренте \"{0}\", удаляем его из нашего списка трекеров!"
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:562
+#, java-format
+msgid "Too many files in \"{0}\" ({1}), deleting it!"
+msgstr "Слишком много файлов в торренте \"{0}\" ({1}), удаляем его!"
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:564
+#, java-format
+msgid "Torrent file \"{0}\" cannot end in '.torrent', deleting it!"
+msgstr "Торрент \"{0}\" содержит единственный файл заканчивающийся на '.torrent', удаляем его!"
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:566
+#, java-format
+msgid "No pieces in \"{0}\", deleting it!"
+msgstr "В торренте \"{0}\" не оказалось ни одной части, удаляем его!"
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:568
+#, java-format
+msgid "Too many pieces in \"{0}\", limit is {1}, deleting it!"
+msgstr "Слишком много частей в торренте \"{0}\" (наш предел {1}), удаляем его!"
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:570
+#, java-format
+msgid "Pieces are too large in \"{0}\" ({1}B), deleting it."
+msgstr "Слишком крупные части в торренте \"{0}\" ({1}B), удаляем его."
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:571
+#, java-format
+msgid "Limit is {0}B"
+msgstr "Наш предел {0}B"
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:579
+#, java-format
+msgid "Torrents larger than {0}B are not supported yet, deleting \"{1}\""
+msgstr "Торренты крупнее чем {0}B пока не поддерживается, удаляем \"{1}\""
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:595
+#, java-format
+msgid "Error: Could not remove the torrent {0}"
+msgstr "Ошибка: Невозможно удалить торрент {0}"
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:616
+#, java-format
+msgid "Torrent stopped: \"{0}\""
+msgstr "Торрент остановлен: \"{0}\""
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:631
+#, java-format
+msgid "Torrent removed: \"{0}\""
+msgstr "Торрент удален: \"{0}\""
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:664
+#, java-format
+msgid "Download finished: \"{0}\""
+msgstr "Завершена загрузка: \"{0}\""
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:664
+#, java-format
+msgid "size: {0}B"
+msgstr "размер: {0}B"
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:692
+msgid "Unable to connect to I2P!"
+msgstr "Не удалось установить соединение с I2P!"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:86
+msgid "I2PSnark - Anonymous BitTorrent Client"
+msgstr "I2PSnark — Анонимный BitTorrent Клиент"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:95
+msgid "Refresh page"
+msgstr "Обновить страницу"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:97
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:656
+msgid "I2PSnark"
+msgstr "I2PSnark"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:99
+msgid "Forum"
+msgstr "Форум"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:125
+msgid "Status"
+msgstr "Статус"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:131
+msgid "Hide Peers"
+msgstr "спрятать список пиров"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:134
+msgid "Show Peers"
+msgstr "показать список пиров"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:139
+msgid "Torrent"
+msgstr "Торрент"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:141
+msgid "ETA"
+msgstr "Осталось"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:143
+msgid "Downloaded"
+msgstr "Получено"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:145
+msgid "Uploaded"
+msgstr "Отдано"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:147
+msgid "Down Rate"
+msgstr "Скорость загрузки"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:149
+msgid "Up Rate"
+msgstr "Скорость отдачи"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:156
+msgid "Stop all torrents and the I2P tunnel"
+msgstr "Остановить все торренты и закрыть соединение с I2P"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:158
+msgid "Stop All"
+msgstr "Остановить все"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:163
+msgid "Start all torrents and the I2P tunnel"
+msgstr "Запустить все торренты и открыть соединение с I2P"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:165
+msgid "Start All"
+msgstr "Запустить все"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:182
+msgid "No torrents loaded."
+msgstr "Нет загруженных торрентов."
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:187
+msgid "Totals"
+msgstr "Всего"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:189
+#, java-format
+msgid "{0} torrents"
+msgstr "{0} торрентов"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:192
+#, java-format
+msgid "{0} connected peers"
+msgstr "{0} подсоединенных пиров"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:227
+#, java-format
+msgid "Torrent file {0} does not exist"
+msgstr "Торрент {0} не существует"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:237
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:986
+#, java-format
+msgid "Torrent already running: {0}"
+msgstr "Торрент уже запущен: {0}"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:239
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:988
+#, java-format
+msgid "Torrent already in the queue: {0}"
+msgstr "Торрент уже в очереди: {0}"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:243
+#, java-format
+msgid "Copying torrent to {0}"
+msgstr "Копируем торрент в: {0}"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:246
+#, java-format
+msgid "Unable to copy the torrent to {0}"
+msgstr "Не удалось скопировать торрент в: {0}"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:246
+#, java-format
+msgid "from {0}"
+msgstr "из: {0}"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:254
+#, java-format
+msgid "Fetching {0}"
+msgstr "Получение торрента: {0}"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:258
+msgid "Invalid URL - must start with http://"
+msgstr "Некорректный URL, должен начинаться с http://"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:288
+#, java-format
+msgid "Starting up torrent {0}"
+msgstr "Запускаем торрент: {0}"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:308
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:326
+#, java-format
+msgid "Torrent file deleted: {0}"
+msgstr "Удален торрент: {0}"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:332
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:342
+#, java-format
+msgid "Data file deleted: {0}"
+msgstr "Файл удален: {0}"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:334
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:344
+#, java-format
+msgid "Data file could not be deleted: {0}"
+msgstr "Не удалось удалить файл: {0}"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:353
+#, java-format
+msgid "Data dir deleted: {0}"
+msgstr "Директория удалена: {0}"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:384
+msgid "Error creating torrent - you must select a tracker"
+msgstr "Торрент не создан — вы должны указать трекер"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:399
+#, java-format
+msgid "Torrent created for \"{0}\""
+msgstr "Создан торрент для \"{0}\""
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:402
+#, java-format
+msgid "Many I2P trackers require you to register new torrents before seeding - please do so before starting \"{0}\""
+msgstr "Многие I2P трекеры требуют зарегистрировать на них торрент перед началом раздачи — пожалуйста проверьте требуется ли это перед запуском \"{0}\""
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:404
+#, java-format
+msgid "Error creating a torrent for \"{0}\""
+msgstr "Ошибка при создании торрента для: \"{0}\""
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:407
+#, java-format
+msgid "Cannot create a torrent for the nonexistent data: {0}"
+msgstr "Невозможно создать торрент для несуществующего файла или директории: {0}"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:410
+msgid "Error creating torrent - you must enter a file or directory"
+msgstr "Торрент не создан — вы должны указать файл или директорию"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:413
+msgid "Stopping all torrents and closing the I2P tunnel."
+msgstr "Останавливаем все торренты и закрываем соединение с I2P"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:422
+msgid "I2P tunnel closed."
+msgstr "Соединение с I2P закрыто."
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:425
+msgid "Opening the I2P tunnel and starting all torrents."
+msgstr "Соединяемся с I2P и запускаем все торренты."
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:502
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:670
+msgid "Unknown"
+msgstr "Неизвестный"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:505
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:509
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:513
+msgid "TrackerErr"
+msgstr "ОшибкаТрекера"
+
+# TODO should replace "uploader limit NN peers" with "global number of upload slots: NN"
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:507
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:509
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:519
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:521
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:528
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:530
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:534
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:536
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:859
+msgid "peers"
+msgstr "пир."
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:517
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:521
+msgid "Seeding"
+msgstr "Раздается"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:523
+msgid "Complete"
+msgstr "Завершен"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:526
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:530
+msgid "OK"
+msgstr "Загружается"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:532
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:536
+msgid "Stalled"
+msgstr "Простаивает"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:538
+msgid "No Peers"
+msgstr "Нет Пиров"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:540
+msgid "Stopped"
+msgstr "Остановлен"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:553
+msgid "View files"
+msgstr "Открыть директорию"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:555
+msgid "Open file"
+msgstr "Открыть файл"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:579
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:779
+msgid "Tracker"
+msgstr "Трекер"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:580
+msgid "Details"
+msgstr "Подробнее"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:614
+msgid "Stop the torrent"
+msgstr "Остановить торрент"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:616
+msgid "Stop"
+msgstr "Остановить"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:622
+msgid "Start the torrent"
+msgstr "Запустить торрент"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:624
+msgid "Start"
+msgstr "Запустить"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:629
+msgid "Remove the torrent from the active list, deleting the .torrent file"
+msgstr "Удалить торрент из списка и с диска"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:631
+msgid "Remove"
+msgstr "Удалить"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:635
+msgid "Delete the .torrent file and the associated data file(s)"
+msgstr "Удалить торрент и стереть загруженные файлы"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:637
+msgid "Delete"
+msgstr "Стереть"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:680
+msgid "Seed"
+msgstr "Сид"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:698
+msgid "Uninteresting (The peer has no pieces we need)"
+msgstr "Uninteresting (У пира нет нужных нам частей торрента)"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:700
+msgid "Choked (The peer is not allowing us to request pieces)"
+msgstr "Choked (Этот пир не позволяет нам запрашивать части торрента)"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:714
+msgid "Uninterested (We have no pieces the peer needs)"
+msgstr "Uninterested (У нас нужных этому пиру частей торрента)"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:716
+msgid "Choking (We are not allowing the peer to request pieces)"
+msgstr "Choking (Мы не позволяем этому пиру запрашивать у нас части торрента)"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:742
+msgid "Add Torrent"
+msgstr "Добавить Торрент"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:744
+msgid "From URL"
+msgstr "Из URL"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:749
+msgid "Add torrent"
+msgstr "Добавить торрент"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:752
+#, java-format
+msgid "Alternately, you can copy .torrent files to the directory {0}."
+msgstr "Ну или вы можете скопировать .torrent-файлы в директорию {0}."
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:754
+msgid "Removing a .torrent file will cause the torrent to stop."
+msgstr "Удаление .torrent-файла приведет к остановке торрента."
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:770
+msgid "Create Torrent"
+msgstr "Создать Торрент"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:773
+msgid "Data to seed"
+msgstr "Файлы для раздачи"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:777
+msgid "File or directory to seed (must be within the specified path)"
+msgstr "Файл или директория для раздачи (вводите только название файла или директории, указание абсолютных путей не поддерживается)"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:781
+msgid "Select a tracker"
+msgstr "Выбрать трекер"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:794
+msgid "or"
+msgstr "или"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:797
+msgid "Specify custom tracker announce URL"
+msgstr "Задать URL анонсера вручную"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:800
+msgid "Create torrent"
+msgstr "Создать торрент"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:817
+msgid "Configuration"
+msgstr "Настройки"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:820
+msgid "Data directory"
+msgstr "Директория для файлов"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:823
+msgid "Directory to store torrents and data"
+msgstr "Директория, где будут храниться торренты и загружаемые файлы"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:825
+msgid "Edit i2psnark.config and restart to change"
+msgstr "Для изменения отредактируйте файл i2psnark.config и перезагрузите I2PSnark"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:829
+msgid "Auto start"
+msgstr "Автозапуск"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:833
+msgid "If checked, automatically start torrents that are added"
+msgstr "Автоматически запускать торренты после добавления"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:856
+msgid "Total uploader limit"
+msgstr "Ограничение количества слотов отдачи"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:863
+msgid "Up bandwidth limit"
+msgstr "Ограничение скорости отдачи"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:866
+msgid "Half available bandwidth recommended."
+msgstr "Рекомендуется использовать половину от доступной пропускной способности."
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:868
+msgid "View or change router bandwidth"
+msgstr "Посмотреть/настроить ограничения скорости в маршрутизаторе I2P"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:872
+msgid "Use open trackers also"
+msgstr "Дополнительно использовать открытые трекеры"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:876
+msgid "If checked, announce torrents to open trackers as well as the tracker listed in the torrent file"
+msgstr "Анонсировать торренты на открытых трекерах, дополнительно к тем, что указаны внутри торрента"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:880
+msgid "Open tracker announce URLs"
+msgstr "URL открытых трекеров"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:891
+msgid "I2CP host"
+msgstr "Адрес I2CP"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:896
+msgid "I2CP port"
+msgstr "Порт I2CP"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:909
+msgid "I2CP options"
+msgstr "Параметры I2CP"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:914
+msgid "Save configuration"
+msgstr "Сохранить настройки"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:967
+#, java-format
+msgid "Torrent fetched from {0}"
+msgstr "Получен торрент из: {0}"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:994
+#, java-format
+msgid "Torrent at {0} was not valid"
+msgstr "Торрент полученный из {0} некорректен"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:999
+#, java-format
+msgid "Torrent was not retrieved from {0}"
+msgstr "Не удалось получить торрент из: {0}"
+
diff --git a/apps/i2psnark/locale/messages_zh.po b/apps/i2psnark/locale/messages_zh.po
new file mode 100644
index 000000000..54759f568
--- /dev/null
+++ b/apps/i2psnark/locale/messages_zh.po
@@ -0,0 +1,652 @@
+# I2P
+# Copyright (C) 2009 The I2P Project
+# This file is distributed under the same license as the i2psnark package.
+# To contribute translations, see http://www.i2p2.de/newdevelopers
+# foo , 2009.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: I2P i2psnark\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-12-18 06:45+0000\n"
+"PO-Revision-Date: 2009-12-27 10:47+0800\n"
+"Last-Translator: walking \n"
+"Language-Team: foo \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Poedit-Language: Chinese\n"
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:84
+#, java-format
+msgid "Adding torrents in {0} minutes"
+msgstr "{0}分钟内完成添加"
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:241
+#, java-format
+msgid "Total uploaders limit changed to {0}"
+msgstr ""
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:243
+#, java-format
+msgid "Minimum total uploaders limit is {0}"
+msgstr ""
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:255
+#, java-format
+msgid "Up BW limit changed to {0}KBps"
+msgstr "上传带宽限制改为 {0} KBps"
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:257
+#, java-format
+msgid "Minimum up bandwidth limit is {0}KBps"
+msgstr "最小上传带宽限制为 {0} KBps"
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:301
+msgid "Cannot change the I2CP settings while torrents are active"
+msgstr "正在下载/上传,无法更改I2CP设置"
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:307
+msgid "Disconnecting old I2CP destination"
+msgstr "正在断开旧的I2CP目标"
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:311
+#, java-format
+msgid "I2CP settings changed to {0}"
+msgstr "I2CP设置改为{0}"
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:315
+msgid "Unable to connect with the new settings, reverting to the old I2CP settings"
+msgstr "无法通过新设置连接,恢复I2CP的旧设置"
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:319
+msgid "Unable to reconnect with the old settings!"
+msgstr "旧设置也无法连接!"
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:321
+msgid "Reconnected on the new I2CP destination"
+msgstr "重新连接新I2CP目标"
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:332
+#, java-format
+msgid "I2CP listener restarted for \"{0}\""
+msgstr "\"{0}\"的I2CP监听端口已启动"
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:343
+msgid "Enabled autostart"
+msgstr "启用自动启动"
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:345
+msgid "Disabled autostart"
+msgstr "禁用自动启动"
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:351
+msgid "Enabled open trackers - torrent restart required to take effect."
+msgstr "启用OpenTracker-重新启动种子后生效"
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:353
+msgid "Disabled open trackers - torrent restart required to take effect."
+msgstr "禁用OpenTracker - 重新启动种子后生效"
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:360
+msgid "Open Tracker list changed - torrent restart required to take effect."
+msgstr "OpenTracker列表已改变 - 重新启动种子后生效"
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:367
+msgid "Configuration unchanged."
+msgstr "设置未改变"
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:377
+#, java-format
+msgid "Unable to save the config to {0}"
+msgstr "无法保存设置到{0}"
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:395
+msgid "Connecting to I2P"
+msgstr "正在连接到I2P"
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:398
+msgid "Error connecting to I2P - check your I2CP settings!"
+msgstr "连接I2P时发生错误 - 请检查I2CP设置!"
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:407
+#, java-format
+msgid "Error: Could not add the torrent {0}"
+msgstr "错误:无法添加种子{0}"
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:446
+#, java-format
+msgid "Torrent in \"{0}\" is invalid"
+msgstr "无效种子 \"{0}\" "
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:461
+#, java-format
+msgid "Torrent added and started: \"{0}\""
+msgstr "已添加并启动种子:\"{0}\""
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:463
+#, java-format
+msgid "Torrent added: \"{0}\""
+msgstr "已添加种子:\"{0}\""
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:559
+#, java-format
+msgid "Non-i2p tracker in \"{0}\", deleting it from our list of trackers!"
+msgstr "【匿名性警告】\"{0}\" 中含有非I2P Tracker,程序将从Tracker列表中将其删除。"
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:562
+#, java-format
+msgid "Too many files in \"{0}\" ({1}), deleting it!"
+msgstr "\"{0}\" ({1}) 含有太多文件,删除之!"
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:564
+#, java-format
+msgid "Torrent file \"{0}\" cannot end in '.torrent', deleting it!"
+msgstr "种子文件 \"{0}\" 不以 \".torrent\"结尾,删除之!"
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:566
+#, java-format
+msgid "No pieces in \"{0}\", deleting it!"
+msgstr "\"{0}\" 中没有数据片,删除之!"
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:568
+#, java-format
+msgid "Too many pieces in \"{0}\", limit is {1}, deleting it!"
+msgstr "\"{0}\" 中文件分片太多,限额为{1},删除之!"
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:570
+#, java-format
+msgid "Pieces are too large in \"{0}\" ({1}B), deleting it."
+msgstr "\"{0}\" ({1}B) 中文件分片过大,删除之。"
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:571
+#, java-format
+msgid "Limit is {0}B"
+msgstr "限额为 {0}B"
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:579
+#, java-format
+msgid "Torrents larger than {0}B are not supported yet, deleting \"{1}\""
+msgstr "目前不支持大于{0}B 的种子,正在删除\"{1}\""
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:595
+#, java-format
+msgid "Error: Could not remove the torrent {0}"
+msgstr "错误:无法删除种子{0}"
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:616
+#, java-format
+msgid "Torrent stopped: \"{0}\""
+msgstr "种子已停止:\"{0}\""
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:631
+#, java-format
+msgid "Torrent removed: \"{0}\""
+msgstr "种子已删除:\"{0}\""
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:664
+#, java-format
+msgid "Download finished: \"{0}\""
+msgstr "下载已完成:\"{0}\""
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:664
+#, java-format
+msgid "size: {0}B"
+msgstr "大小:{0}B"
+
+#: ../java/src/org/klomp/snark/SnarkManager.java:692
+msgid "Unable to connect to I2P!"
+msgstr "无法连接至I2P!"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:86
+msgid "I2PSnark - Anonymous BitTorrent Client"
+msgstr "I2PSnark - 匿名BitTorrent客户端"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:95
+msgid "Refresh page"
+msgstr "刷新页面"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:97
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:656
+msgid "I2PSnark"
+msgstr ""
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:99
+msgid "Forum"
+msgstr "论坛"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:125
+msgid "Status"
+msgstr "状态"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:131
+msgid "Hide Peers"
+msgstr "隐藏用户"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:134
+msgid "Show Peers"
+msgstr "显示用户"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:139
+msgid "Torrent"
+msgstr "种子"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:141
+msgid "ETA"
+msgstr ""
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:143
+msgid "Downloaded"
+msgstr "已下载"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:145
+msgid "Uploaded"
+msgstr "已上传"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:147
+msgid "Down Rate"
+msgstr "下载速度"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:149
+msgid "Up Rate"
+msgstr "上传速度"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:156
+msgid "Stop all torrents and the I2P tunnel"
+msgstr "停止全部种子及I2P隧道"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:158
+msgid "Stop All"
+msgstr "停止全部"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:163
+msgid "Start all torrents and the I2P tunnel"
+msgstr "启动全部种子及I2P隧道"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:165
+msgid "Start All"
+msgstr "启动全部"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:182
+msgid "No torrents loaded."
+msgstr "未载入任何种子"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:187
+msgid "Totals"
+msgstr "总计"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:189
+#, java-format
+msgid "{0} torrents"
+msgstr "{0} 个种子"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:192
+#, java-format
+msgid "{0} connected peers"
+msgstr "{0} 已连接用户"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:227
+#, java-format
+msgid "Torrent file {0} does not exist"
+msgstr "种子文件{0}不存在"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:237
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:990
+#, java-format
+msgid "Torrent already running: {0}"
+msgstr "种子已启动:{0}"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:239
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:992
+#, java-format
+msgid "Torrent already in the queue: {0}"
+msgstr "种子排队中:{0}"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:243
+#, java-format
+msgid "Copying torrent to {0}"
+msgstr "正在复制种子到{0}"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:246
+#, java-format
+msgid "Unable to copy the torrent to {0}"
+msgstr "无法复制种子文件到{0}"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:246
+#, java-format
+msgid "from {0}"
+msgstr "来源{0}"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:254
+#, java-format
+msgid "Fetching {0}"
+msgstr "正在获取{0}"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:258
+msgid "Invalid URL - must start with http://"
+msgstr "无效链接 - 必须以http:// 开头"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:288
+#, java-format
+msgid "Starting up torrent {0}"
+msgstr "正在启动种子{0}"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:308
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:326
+#, java-format
+msgid "Torrent file deleted: {0}"
+msgstr "种子文件已删除:{0}"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:332
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:342
+#, java-format
+msgid "Data file deleted: {0}"
+msgstr "数据文件已删除:{0}"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:334
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:344
+#, java-format
+msgid "Data file could not be deleted: {0}"
+msgstr "无法删除数据文件:{0}"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:353
+#, java-format
+msgid "Data dir deleted: {0}"
+msgstr "数据文件夹已删除:{0}"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:384
+msgid "Error creating torrent - you must select a tracker"
+msgstr "创建种子时发生错误 - 您必须选择一个Tracker"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:399
+#, java-format
+msgid "Torrent created for \"{0}\""
+msgstr "种子创建成功\"{0}\""
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:402
+#, java-format
+msgid "Many I2P trackers require you to register new torrents before seeding - please do so before starting \"{0}\""
+msgstr "多数I2PTracker需要用户在做种前注册新种子 - 请在启动 \"{0}\"前到所使用的Tracker进行注册。"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:404
+#, java-format
+msgid "Error creating a torrent for \"{0}\""
+msgstr "创建种子时发生错误 \"{0}\""
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:407
+#, java-format
+msgid "Cannot create a torrent for the nonexistent data: {0}"
+msgstr "无法为不存在的数据文件创建种子:{0}"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:410
+msgid "Error creating torrent - you must enter a file or directory"
+msgstr "创建种子时发生错误 - 必须指定文件或文件夹"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:413
+msgid "Stopping all torrents and closing the I2P tunnel."
+msgstr "正在停用所有种子并关闭I2P隧道。"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:422
+msgid "I2P tunnel closed."
+msgstr "I2P隧道已关闭"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:425
+msgid "Opening the I2P tunnel and starting all torrents."
+msgstr "正在打开I2P隧道并启动所有种子"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:502
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:670
+msgid "Unknown"
+msgstr "未知"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:505
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:509
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:513
+msgid "TrackerErr"
+msgstr "Tracker错误"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:507
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:509
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:519
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:521
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:528
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:530
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:534
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:536
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:862
+msgid "peers"
+msgstr "用户"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:517
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:521
+msgid "Seeding"
+msgstr "正做种"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:523
+msgid "Complete"
+msgstr "完成"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:526
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:530
+msgid "OK"
+msgstr "确定"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:532
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:536
+msgid "Stalled"
+msgstr "等待"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:538
+msgid "No Peers"
+msgstr "没有用户"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:540
+msgid "Stopped"
+msgstr "已停用"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:553
+msgid "View files"
+msgstr "浏览文件"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:555
+msgid "Open file"
+msgstr "打开文件"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:579
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:781
+msgid "Tracker"
+msgstr "Tracker服务器"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:580
+msgid "Details"
+msgstr "详情"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:614
+msgid "Stop the torrent"
+msgstr "停止种子"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:616
+msgid "Stop"
+msgstr "停止"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:622
+msgid "Start the torrent"
+msgstr "启动种子"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:624
+msgid "Start"
+msgstr "启动"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:629
+msgid "Remove the torrent from the active list, deleting the .torrent file"
+msgstr "取消下载任务并删除对应种子文件。"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:631
+msgid "Remove"
+msgstr "移除"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:635
+msgid "Delete the .torrent file and the associated data file(s)"
+msgstr "删除种子及所下载的文件"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:637
+msgid "Delete"
+msgstr "删除"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:680
+msgid "Seed"
+msgstr "种子"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:698
+msgid "Uninteresting (The peer has no pieces we need)"
+msgstr "无需要部分"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:700
+msgid "Choked (The peer is not allowing us to request pieces)"
+msgstr "拒绝请求"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:714
+msgid "Uninterested (We have no pieces the peer needs)"
+msgstr "无需要部分"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:716
+msgid "Choking (We are not allowing the peer to request pieces)"
+msgstr "拒绝请求"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:743
+msgid "Add Torrent"
+msgstr "添加种子"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:745
+msgid "From URL"
+msgstr "从URL"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:750
+msgid "Add torrent"
+msgstr "添加种子"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:753
+#, java-format
+msgid "Alternately, you can copy .torrent files to the directory {0}."
+msgstr "或者您可以将.torrent文件复制到以下目录{0}."
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:755
+msgid "Removing a .torrent file will cause the torrent to stop."
+msgstr "删除种子文件将导致中止该下载任务。"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:772
+msgid "Create Torrent"
+msgstr "创建种子"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:775
+msgid "Data to seed"
+msgstr "做种数据"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:779
+msgid "File or directory to seed (must be within the specified path)"
+msgstr "做种文件或文件夹(必须下面为Snark指定的文件夹中)"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:783
+msgid "Select a tracker"
+msgstr "选择一个Tracker"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:796
+msgid "or"
+msgstr "或"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:799
+msgid "Specify custom tracker announce URL"
+msgstr "指定Open Tracker发布链接"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:802
+msgid "Create torrent"
+msgstr "创建种子"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:820
+msgid "Configuration"
+msgstr "设置"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:823
+msgid "Data directory"
+msgstr "数据文件夹"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:826
+msgid "Directory to store torrents and data"
+msgstr "种子及被做种文件的保存位置。"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:828
+msgid "Edit i2psnark.config and restart to change"
+msgstr "编辑 i2psnark.config 并重启Snark后生效"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:832
+msgid "Auto start"
+msgstr "自动启动"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:836
+msgid "If checked, automatically start torrents that are added"
+msgstr "选中后Snark将自动启动已添加的所有种子。"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:859
+msgid "Total uploader limit"
+msgstr ""
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:866
+msgid "Up bandwidth limit"
+msgstr "上传带宽限制"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:869
+msgid "Half available bandwidth recommended."
+msgstr "推荐设置为可用带宽的一半。"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:871
+msgid "View or change router bandwidth"
+msgstr "浏览或修改路由器带宽"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:875
+msgid "Use open trackers also"
+msgstr "同时使用OpenTracker"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:879
+msgid "If checked, announce torrents to open trackers as well as the tracker listed in the torrent file"
+msgstr "选择后在OpenTracker及种子文件中的Tracker上同时发布。"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:883
+msgid "Open tracker announce URLs"
+msgstr "Open Tracker发布链接"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:894
+msgid "I2CP host"
+msgstr "I2CP主机"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:899
+msgid "I2CP port"
+msgstr "I2CP端口"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:912
+msgid "I2CP options"
+msgstr "I2CP选项"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:917
+msgid "Save configuration"
+msgstr "保存设置"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:970
+#, java-format
+msgid "Torrent fetched from {0}"
+msgstr "从{0}获取种子成功"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:998
+#, java-format
+msgid "Torrent at {0} was not valid"
+msgstr "{0}的种子中有错误"
+
+#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1003
+#, java-format
+msgid "Torrent was not retrieved from {0}"
+msgstr "从{0}获得种子失败"
+
+#~ msgid "Custom tracker URL"
+#~ msgstr "自定义TrackerURL"
+#~ msgid "Configure"
+#~ msgstr "设置"
+
diff --git a/apps/i2ptunnel/java/build.xml b/apps/i2ptunnel/java/build.xml
index fa3e5d677..9647fa8d1 100644
--- a/apps/i2ptunnel/java/build.xml
+++ b/apps/i2ptunnel/java/build.xml
@@ -41,10 +41,8 @@
-
-
-
+
diff --git a/apps/i2ptunnel/java/bundle-messages.sh b/apps/i2ptunnel/java/bundle-messages.sh
index aa98a3167..8e9375d20 100755
--- a/apps/i2ptunnel/java/bundle-messages.sh
+++ b/apps/i2ptunnel/java/bundle-messages.sh
@@ -31,9 +31,8 @@ do
# make list of java files newer than the .po file
find $JPATHS -name *.java -newer $i > $TMPFILE
fi
-
- if [ -s build/obj/net/i2p/i2ptunnel/web/messages_$LG.class -a \
- build/obj/net/i2p/i2ptunnel/web/messages_$LG.class -nt $i -a \
+ if [ -s ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/web/messages_$LG.class -a \
+ ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/web/messages_$LG.class -nt $i -a \
! -s $TMPFILE ]
then
continue
@@ -76,7 +75,7 @@ do
echo "Generating ${CLASS}_$LG ResourceBundle..."
# convert to class files in build/obj
- msgfmt --java -r $CLASS -l $LG -d build/obj $i
+ msgfmt --java --statistics -r $CLASS -l $LG -d ../jsp/WEB-INF/classes $i
if [ $? -ne 0 ]
then
echo 'Warning - msgfmt failed, not updating translations'
diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java
index df0d75019..3598ac05c 100644
--- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java
+++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java
@@ -32,6 +32,8 @@ import net.i2p.util.EventDispatcher;
import net.i2p.util.FileUtil;
import net.i2p.util.Log;
+import net.i2p.util.Translate;
+
/**
* Act as a mini HTTP proxy, handling various different types of requests,
* forwarding them through I2P appropriately, and displaying the reply. Supported
@@ -41,7 +43,7 @@ import net.i2p.util.Log;
* $method $path $protocolVersion\nHost: $site
* or
* $method http://i2p/$b64key/$path $protocolVersion
- * or
+ * or
* $method /$site/$path $protocolVersion
*
*
@@ -70,7 +72,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
"
I2P ERROR: REQUEST DENIED
"+
"You attempted to connect to a non-I2P website or location. ")
.getBytes();
-
+
private final static byte[] ERR_DESTINATION_UNKNOWN =
("HTTP/1.1 503 Service Unavailable\r\n"+
"Content-Type: text/html; charset=iso-8859-1\r\n"+
@@ -80,10 +82,10 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
"That I2P Destination was not found. Perhaps you pasted in the "+
"wrong BASE64 I2P Destination or the link you are following is "+
"bad. The host (or the WWW proxy, if you're using one) could also "+
- "be temporarily offline. You may want to retry. "+
+ "be temporarily offline. You may want to retry. "+
"Could not find the following Destination:
")
.getBytes();
-
+
/*****
private final static byte[] ERR_TIMEOUT =
("HTTP/1.1 504 Gateway Timeout\r\n"+
@@ -107,7 +109,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
"Your request was for a site outside of I2P, but you have no "+
"HTTP outproxy configured. Please configure an outproxy in I2PTunnel")
.getBytes();
-
+
private final static byte[] ERR_AHELPER_CONFLICT =
("HTTP/1.1 409 Conflict\r\n"+
"Content-Type: text/html; charset=iso-8859-1\r\n"+
@@ -123,7 +125,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
"discarding the host entry from your host database, "+
"or naming one of them differently.
")
.getBytes();
-
+
private final static byte[] ERR_BAD_PROTOCOL =
("HTTP/1.1 403 Bad Protocol\r\n"+
"Content-Type: text/html; charset=iso-8859-1\r\n"+
@@ -133,7 +135,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
"The request uses a bad protocol. "+
"The I2P HTTP Proxy supports http:// requests ONLY. Other protocols such as https:// and ftp:// are not allowed. ")
.getBytes();
-
+
private final static byte[] ERR_LOCALHOST =
("HTTP/1.1 403 Access Denied\r\n"+
"Content-Type: text/html; charset=iso-8859-1\r\n"+
@@ -142,7 +144,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
"
I2P ERROR: REQUEST DENIED
"+
"Your browser is misconfigured. Do not use the proxy to access the router console or other localhost destinations. ")
.getBytes();
-
+
/** used to assign unique IDs to the threads / clients. no logic or functionality */
private static volatile long __clientId = 0;
@@ -153,8 +155,8 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
* @throws IllegalArgumentException if the I2PTunnel does not contain
* valid config to contact the router
*/
- public I2PTunnelHTTPClient(int localPort, Logging l, boolean ownDest,
- String wwwProxy, EventDispatcher notifyThis,
+ public I2PTunnelHTTPClient(int localPort, Logging l, boolean ownDest,
+ String wwwProxy, EventDispatcher notifyThis,
I2PTunnel tunnel) throws IllegalArgumentException {
super(localPort, ownDest, l, notifyThis, "HTTPHandler " + (++__clientId), tunnel);
@@ -178,7 +180,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
}
private String getPrefix(long requestId) { return "Client[" + _clientId + "/" + requestId + "]: "; }
-
+
private String selectProxy() {
synchronized (proxyList) {
int size = proxyList.size();
@@ -195,8 +197,8 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
}
private static final int DEFAULT_READ_TIMEOUT = 60*1000;
-
- /**
+
+ /**
* create the default options (using the default timeout, etc)
* unused?
*/
@@ -212,8 +214,8 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
opts.setConnectTimeout(DEFAULT_CONNECT_TIMEOUT);
return opts;
}
-
- /**
+
+ /**
* create the default options (using the default timeout, etc)
*
*/
@@ -261,7 +263,8 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
public static final String PROP_REFERER = "i2ptunnel.httpclient.sendReferer";
public static final String PROP_USER_AGENT = "i2ptunnel.httpclient.sendUserAgent";
public static final String PROP_VIA = "i2ptunnel.httpclient.sendVia";
-
+ public static final String PROP_JUMP_SERVERS = "i2ptunnel.httpclient.jumpServers";
+
private static long __requestId = 0;
protected void clientConnectionRun(Socket s) {
InputStream in = null;
@@ -281,17 +284,17 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
line = line.trim();
if (_log.shouldLog(Log.DEBUG))
_log.debug(getPrefix(requestId) + "Line=[" + line + "]");
-
+
String lowercaseLine = line.toLowerCase();
- if (lowercaseLine.startsWith("connection: ") ||
- lowercaseLine.startsWith("keep-alive: ") ||
+ if (lowercaseLine.startsWith("connection: ") ||
+ lowercaseLine.startsWith("keep-alive: ") ||
lowercaseLine.startsWith("proxy-connection: "))
continue;
-
+
if (method == null) { // first line (GET /base64/realaddr)
if (_log.shouldLog(Log.DEBUG))
_log.debug(getPrefix(requestId) + "Method is null for [" + line + "]");
-
+
int pos = line.indexOf(" ");
if (pos == -1) break;
method = line.substring(0, pos);
@@ -327,7 +330,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
break;
}
host = request.substring(0, pos);
-
+
// parse port
int posPort = host.indexOf(":");
int port = 80;
@@ -340,7 +343,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
// TODO: log this
}
}
-
+
if (host.toLowerCase().equals("proxy.i2p")) {
// so we don't do any naming service lookups
destination = "proxy.i2p";
@@ -357,7 +360,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
// and split the request into it's component parts for rebuilding later
String ahelperKey = null;
boolean ahelperConflict = false;
-
+
String fragments = request.substring(pos2 + 1);
String uriPath = request.substring(0, pos2);
pos2 = fragments.indexOf(" ");
@@ -371,15 +374,15 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
pos2 = fragments.indexOf("&");
fragment = fragments.substring(0, pos2);
fragments = fragments.substring(pos2 + 1);
-
+
// Fragment looks like addresshelper key
if (fragment.startsWith("i2paddresshelper=")) {
pos2 = fragment.indexOf("=");
ahelperKey = fragment.substring(pos2 + 1);
-
+
// Key contains data, lets not ignore it
if (ahelperKey != null) {
-
+
// Host resolvable only with addresshelper
if ( (host == null) || ("i2p".equals(host)) )
{
@@ -403,25 +406,25 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
if ("".equals(urlEncoding)) {
urlEncoding = "?" + fragment;
} else {
- urlEncoding = urlEncoding + "&" + fragment;
+ urlEncoding = urlEncoding + "&" + fragment;
}
}
}
// Reconstruct the request minus the i2paddresshelper GET var
request = uriPath + urlEncoding + " " + protocolVersion;
-
+
// Did addresshelper key conflict?
if (ahelperConflict)
{
if (out != null) {
- // Fixme untranslated
long alias = I2PAppContext.getGlobalContext().random().nextLong();
String trustedURL = protocol + uriPath + urlEncoding;
String conflictURL = protocol + alias + ".i2p/?" + initialFragments;
byte[] header = getErrorPage("ahelper-conflict", ERR_AHELPER_CONFLICT);
out.write(header);
- out.write(("To visit the destination in your host database, click here. To visit the conflicting addresshelper link by temporarily giving it a random alias, click here.
").getBytes());
+ out.write(_("To visit the destination in your host database, click here. To visit the conflicting addresshelper link by temporarily giving it a random alias, click here.", trustedURL, conflictURL).getBytes("UTF-8"));
+ out.write(("
").getBytes());
writeFooter(out);
}
s.close();
@@ -435,7 +438,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
host = getHostName(destination);
ahelper = 1;
}
-
+
line = method + " " + request.substring(pos);
} else if (host.toLowerCase().equals("localhost") || host.equals("127.0.0.1")) {
if (out != null) {
@@ -507,7 +510,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
} else {
if (lowercaseLine.startsWith("host: ") && !usingWWWProxy) {
line = "Host: " + host;
- if (_log.shouldLog(Log.INFO))
+ if (_log.shouldLog(Log.INFO))
_log.info(getPrefix(requestId) + "Setting host = " + host);
} else if (lowercaseLine.startsWith("user-agent: ") &&
!Boolean.valueOf(getTunnel().getClientOptions().getProperty(PROP_USER_AGENT)).booleanValue()) {
@@ -537,7 +540,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
}
if (line.length() == 0) {
-
+
String ok = getTunnel().getClientOptions().getProperty("i2ptunnel.gzip");
boolean gzip = DEFAULT_GZIP;
if (ok != null)
@@ -573,10 +576,10 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
s.close();
return;
}
-
+
if (_log.shouldLog(Log.DEBUG))
_log.debug(getPrefix(requestId) + "Destination: " + destination);
-
+
// Serve local proxy files (images, css linked from error pages)
// Ignore all the headers
if (usingInternalServer) {
@@ -591,7 +594,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
if (_log.shouldLog(Log.WARN))
_log.warn("Unable to resolve " + destination + " (proxy? " + usingWWWProxy + ", request: " + targetRequest);
byte[] header;
- boolean showAddrHelper = false;
+ String jumpServers = null;
if (usingWWWProxy)
header = getErrorPage("dnfp", ERR_DESTINATION_UNKNOWN);
else if(ahelper != 0)
@@ -600,14 +603,16 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
header = getErrorPage("dnf", ERR_DESTINATION_UNKNOWN);
else {
header = getErrorPage("dnfh", ERR_DESTINATION_UNKNOWN);
- showAddrHelper = true;
+ jumpServers = getTunnel().getClientOptions().getProperty(PROP_JUMP_SERVERS);
+ if (jumpServers == null)
+ jumpServers = DEFAULT_JUMP_SERVERS;
}
- writeErrorMessage(header, out, targetRequest, usingWWWProxy, destination, showAddrHelper);
+ writeErrorMessage(header, out, targetRequest, usingWWWProxy, destination, jumpServers);
s.close();
return;
}
String remoteID;
-
+
Properties opts = new Properties();
//opts.setProperty("i2p.streaming.inactivityTimeout", ""+120*1000);
// 1 == disconnect. see ConnectionOptions in the new streaming lib, which i
@@ -751,21 +756,22 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
public void run() {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Timeout occured requesting " + _target);
- handleHTTPClientException(new RuntimeException("Timeout"), _out,
+ handleHTTPClientException(new RuntimeException("Timeout"), _out,
_target, _usingProxy, _wwwProxy, _requestId);
closeSocket(_socket);
}
}
-
- private static String jumpServers[] = {
- "http://i2host.i2p/cgi-bin/i2hostjump?",
- // "http://orion.i2p/jump/",
- "http://stats.i2p/cgi-bin/jump.cgi?a=",
- // "http://trevorreznik.i2p/cgi-bin/jump.php?hostname=",
- "http://i2jump.i2p/"
- };
+
+ private static String DEFAULT_JUMP_SERVERS =
+ "http://i2host.i2p/cgi-bin/i2hostjump?," +
+ "http://stats.i2p/cgi-bin/jump.cgi?a=," +
+ "http://i2jump.i2p/";
+
+ /**
+ * @param jumpServers comma- or space-separated list, or null
+ */
private static void writeErrorMessage(byte[] errMessage, OutputStream out, String targetRequest,
- boolean usingWWWProxy, String wwwProxy, boolean showAddrHelper) throws IOException {
+ boolean usingWWWProxy, String wwwProxy, String jumpServers) throws IOException {
if (out != null) {
out.write(errMessage);
if (targetRequest != null) {
@@ -781,12 +787,18 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
out.write(uri.getBytes());
out.write("".getBytes());
if (usingWWWProxy) out.write((" WWW proxy: " + wwwProxy).getBytes());
- if (showAddrHelper) {
- // Fixme untranslated
- out.write("
Click a link below to look for an address helper by using a \"jump\" service: ".getBytes());
- for (int i = 0; i < jumpServers.length; i++) {
+ if (jumpServers != null && jumpServers.length() > 0) {
+ out.write("
".getBytes());
+ out.write(_("Click a link below to look for an address helper by using a \"jump\" service:").getBytes("UTF-8"));
+ out.write(" ".getBytes());
+
+ StringTokenizer tok = new StringTokenizer(jumpServers, ", ");
+ while (tok.hasMoreTokens()) {
+ String jurl = tok.nextToken();
+ if (!jurl.startsWith("http://"))
+ continue;
// Skip jump servers we don't know
- String jumphost = jumpServers[i].substring(7); // "http://"
+ String jumphost = jurl.substring(7); // "http://"
jumphost = jumphost.substring(0, jumphost.indexOf('/'));
try {
Destination dest = I2PTunnel.destFromName(jumphost);
@@ -796,10 +808,10 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
}
out.write(" ".getBytes());
- out.write(jumpServers[i].getBytes());
+ out.write(jurl.getBytes());
out.write(uri.getBytes());
out.write("".getBytes());
}
@@ -812,7 +824,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
private static void handleHTTPClientException(Exception ex, OutputStream out, String targetRequest,
boolean usingWWWProxy, String wwwProxy, long requestId) {
-
+
// static
//if (_log.shouldLog(Log.WARN))
// _log.warn(getPrefix(requestId) + "Error sending to " + wwwProxy + " (proxy? " + usingWWWProxy + ", request: " + targetRequest, ex);
@@ -823,7 +835,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
header = getErrorPage(I2PAppContext.getGlobalContext(), "dnfp", ERR_DESTINATION_UNKNOWN);
else
header = getErrorPage(I2PAppContext.getGlobalContext(), "dnf", ERR_DESTINATION_UNKNOWN);
- writeErrorMessage(header, out, targetRequest, usingWWWProxy, wwwProxy, false);
+ writeErrorMessage(header, out, targetRequest, usingWWWProxy, wwwProxy, null);
} catch (IOException ioe) {
// static
//_log.warn(getPrefix(requestId) + "Error writing out the 'destination was unknown' " + "message", ioe);
@@ -933,4 +945,18 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
out.flush();
} catch (IOException ioe) {}
}
+
+
+ private static final String BUNDLE_NAME = "net.i2p.i2ptunnel.web.messages";
+
+ /** lang in routerconsole.lang property, else current locale */
+ public static String _(String key) {
+ return Translate.getString(key, I2PAppContext.getGlobalContext(), BUNDLE_NAME);
+ }
+
+ /** {0} and {1} */
+ public static String _(String key, Object o, Object o2) {
+ return Translate.getString(key, o, o2, I2PAppContext.getGlobalContext(), BUNDLE_NAME);
+ }
+
}
diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/InternalSocketRunner.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/InternalSocketRunner.java
index 5e3eefd4f..d6f4dcc39 100644
--- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/InternalSocketRunner.java
+++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/InternalSocketRunner.java
@@ -12,6 +12,7 @@ import net.i2p.util.Log;
* Listen for in-JVM connections on the internal "socket"
*
* @author zzz
+ * @since 0.7.9
*/
class InternalSocketRunner implements Runnable {
private I2PTunnelClientBase client;
diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/IndexBean.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/IndexBean.java
index 53ed82749..6951286dc 100644
--- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/IndexBean.java
+++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/IndexBean.java
@@ -359,7 +359,7 @@ public class IndexBean {
if (tun != null && tun.getName() != null)
return tun.getName();
else
- return "New Tunnel";
+ return _("New Tunnel");
}
public String getClientPort(int tunnel) {
@@ -379,16 +379,16 @@ public class IndexBean {
}
public String getTypeName(String internalType) {
- if ("client".equals(internalType)) return "Standard client";
- else if ("httpclient".equals(internalType)) return "HTTP client";
- else if ("ircclient".equals(internalType)) return "IRC client";
- else if ("server".equals(internalType)) return "Standard server";
- else if ("httpserver".equals(internalType)) return "HTTP server";
- else if ("sockstunnel".equals(internalType)) return "SOCKS 4/4a/5 proxy";
- else if ("connectclient".equals(internalType)) return "CONNECT/SSL/HTTPS proxy";
- else if ("ircserver".equals(internalType)) return "IRC server";
- else if ("streamrclient".equals(internalType)) return "Streamr client";
- else if ("streamrserver".equals(internalType)) return "Streamr server";
+ if ("client".equals(internalType)) return _("Standard client");
+ else if ("httpclient".equals(internalType)) return _("HTTP client");
+ else if ("ircclient".equals(internalType)) return _("IRC client");
+ else if ("server".equals(internalType)) return _("Standard server");
+ else if ("httpserver".equals(internalType)) return _("HTTP server");
+ else if ("sockstunnel".equals(internalType)) return _("SOCKS 4/4a/5 proxy");
+ else if ("connectclient".equals(internalType)) return _("CONNECT/SSL/HTTPS proxy");
+ else if ("ircserver".equals(internalType)) return _("IRC server");
+ else if ("streamrclient".equals(internalType)) return _("Streamr client");
+ else if ("streamrserver".equals(internalType)) return _("Streamr server");
else return internalType;
}
@@ -935,4 +935,8 @@ public class IndexBean {
buf.append((String)msgs.get(i)).append("\n");
}
}
+
+ private String _(String key) {
+ return Messages._(key, _context);
+ }
}
diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/Messages.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/Messages.java
index fa3839232..071123a2e 100644
--- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/Messages.java
+++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/Messages.java
@@ -5,9 +5,10 @@ import net.i2p.util.Translate;
/**
* Translate strings for this package.
+ * @since 0.7.9
*/
public class Messages {
- private static final String BUNDLE_NAME = "net.i2p.i2ptunnel.messages";
+ private static final String BUNDLE_NAME = "net.i2p.i2ptunnel.web.messages";
private final I2PAppContext _context;
public Messages() {
@@ -19,6 +20,10 @@ public class Messages {
return Translate.getString(key, _context, BUNDLE_NAME);
}
+ public static String _(String key, I2PAppContext ctx) {
+ return Translate.getString(key, ctx, BUNDLE_NAME);
+ }
+
/**
* translate a string with a parameter
* This is a lot more expensive than getString(s, ctx), so use sparingly.
diff --git a/apps/i2ptunnel/jsp/editClient.jsp b/apps/i2ptunnel/jsp/editClient.jsp
index 40d1028b0..a51dead90 100644
--- a/apps/i2ptunnel/jsp/editClient.jsp
+++ b/apps/i2ptunnel/jsp/editClient.jsp
@@ -39,11 +39,11 @@
if (curTunnel >= 0) {
tunnelTypeName = editBean.getTunnelType(curTunnel);
tunnelType = editBean.getInternalType(curTunnel);
- %>
class="tickbox" />
- (Share tunnels with other clients and irc/httpclients? Change requires restart of client proxy)
+ <%=intl._("(Share tunnels with other clients and irc/httpclients? Change requires restart of client proxy)")%>
<% } // !streamrclient %>
class="tickbox" />
- (Check the Box for 'YES')
+ <%=intl._("(Check the Box for 'YES')")%>
");
if (cfg.getReceiveTunnel() != null)
- out.write("
" + cfg.getReceiveTunnel().getTunnelId() +"
");
+ out.write("
" + cfg.getReceiveTunnel().getTunnelId() +"
");
else
- out.write("
n/a
");
+ out.write("
n/a
");
if (cfg.getReceiveFrom() != null)
- out.write("
" + netDbLink(cfg.getReceiveFrom()) +"
");
+ out.write("
" + netDbLink(cfg.getReceiveFrom()) +"
");
else
- out.write("
");
+ out.write("
");
if (cfg.getSendTunnel() != null)
- out.write("
" + cfg.getSendTunnel().getTunnelId() +"
");
+ out.write("
" + cfg.getSendTunnel().getTunnelId() +"
");
else
- out.write("
");
+ out.write("
");
if (cfg.getSendTo() != null)
- out.write("
" + netDbLink(cfg.getSendTo()) +"
");
+ out.write("
" + netDbLink(cfg.getSendTo()) +"
");
else
-// out.write("
");
- out.write("
");
+ out.write("
");
long timeLeft = cfg.getExpiration()-_context.clock().now();
if (timeLeft > 0)
- out.write("
" + DataHelper.formatDuration(timeLeft) + "
");
+ out.write("
" + DataHelper.formatDuration(timeLeft) + "
");
else
- out.write("
(" + _("grace period") + ")
");
- out.write("
" + cfg.getProcessedMessagesCount() + "KB
");
+ out.write("
(" + _("grace period") + ")
");
+ out.write("
" + cfg.getProcessedMessagesCount() + "KB
");
int lifetime = (int) ((_context.clock().now() - cfg.getCreation()) / 1000);
if (lifetime <= 0)
lifetime = 1;
if (lifetime > 10*60)
lifetime = 10*60;
int bps = 1024 * (int) cfg.getProcessedMessagesCount() / lifetime;
- out.write("
" + bps + "Bps
");
+ out.write("
" + bps + "Bps
");
if (cfg.getSendTo() == null)
- out.write("
" + _("Outbound Endpoint") + "
");
+ out.write("
" + _("Outbound Endpoint") + "
");
else if (cfg.getReceiveFrom() == null)
- out.write("
" + _("Inbound Gateway") + "
");
+ out.write("
" + _("Inbound Gateway") + "
");
else
- out.write("
" + _("Participant") + "
");
+ out.write("
" + _("Participant") + "
");
out.write("
\n");
processed += cfg.getProcessedMessagesCount();
}
@@ -229,10 +229,10 @@ public class TunnelRenderer {
Set peers = new HashSet(lc.objects());
peers.addAll(pc.objects());
List peerList = new ArrayList(peers);
- Collections.sort(peerList, new HashComparator());
+ Collections.sort(peerList, new CountryComparator(this._context.commSystem()));
out.write("
" + _("Tunnel Counts By Peer") + "
\n");
- out.write("
" + _("Peer") + "
" + _("Expl. + Client") + "
" + _("% of total") + "
" + _("Part. from + to") + "
" + _("% of total") + "
\n");
+ out.write("
" + _("Peer") + "
" + _("Our Tunnels") + "
" + _("% of total") + "
" + _("Participating Tunnels") + "
" + _("% of total") + "
\n");
for (Hash h : peerList) {
out.write("
");
out.write(netDbLink(h));
@@ -250,7 +250,7 @@ public class TunnelRenderer {
out.write('0');
out.write('\n');
}
- out.write("
" + _("Tunnels") + "
" + tunnelCount);
+ out.write("
" + _("Totals") + "
" + tunnelCount);
out.write("
" + partCount);
out.write("
\n");
}
@@ -295,6 +295,26 @@ public class TunnelRenderer {
return ((Hash)l).toBase64().compareTo(((Hash)r).toBase64());
}
}
+
+ private static class CountryComparator implements Comparator {
+ public CountryComparator(CommSystemFacade comm) {
+ this.comm = comm;
+ }
+ public int compare(Hash l, Hash r) {
+ // get both countries
+ String lc = this.comm.getCountry(l);
+ String rc = this.comm.getCountry(r);
+
+ // make them non-null
+ lc = (lc == null) ? "zzzz" : lc;
+ rc = (rc == null) ? "zzzz" : rc;
+
+ // let String handle the rest
+ return lc.compareTo(rc);
+ }
+
+ private CommSystemFacade comm;
+ }
private String getCapacity(Hash peer) {
RouterInfo info = _context.netDb().lookupRouterInfoLocally(peer);
diff --git a/apps/routerconsole/java/strings/Strings.java b/apps/routerconsole/java/strings/Strings.java
index cddec4197..0805d479a 100644
--- a/apps/routerconsole/java/strings/Strings.java
+++ b/apps/routerconsole/java/strings/Strings.java
@@ -52,5 +52,24 @@ class Dummy {
_("dark");
_("light");
_("midnight");
+
+ // stat groups for stats.jsp
+ _("Bandwidth");
+ _("BandwidthLimiter");
+ _("ClientMessages");
+ _("Encryption");
+ _("i2cp");
+ _("I2PTunnel");
+ _("InNetPool");
+ _("JobQueue");
+ _("NetworkDatabase");
+ _("ntcp");
+ _("Peers");
+ _("Router");
+ _("Stream");
+ _("Throttle");
+ _("Transport");
+ _("Tunnels");
+ _("udp");
}
}
diff --git a/apps/routerconsole/jsp/config.jsp b/apps/routerconsole/jsp/config.jsp
index 9a9942c79..edd02bba6 100644
--- a/apps/routerconsole/jsp/config.jsp
+++ b/apps/routerconsole/jsp/config.jsp
@@ -122,6 +122,11 @@
/>
<%=intl._("Hidden mode - do not publish IP")%> <%=intl._("(prevents participating traffic)")%>
+
+ <%=intl._("Action when IP changes")%>:
+ />
+ <%=intl._("Laptop mode - Change router identity and UDP port when IP changes for enhanced anonymity")%>
+ (<%=intl._("Experimental")%>)