@ -1,18 +0,0 @@
@@ -1,18 +0,0 @@
|
||||
gen |
||||
tests |
||||
bin |
||||
libs |
||||
log* |
||||
obj |
||||
.cxx |
||||
.gradle |
||||
.idea |
||||
.externalNativeBuild |
||||
ant.properties |
||||
local.properties |
||||
build.sh |
||||
android.iml |
||||
build |
||||
*.iml |
||||
*.local |
||||
*.jks |
@ -1,60 +0,0 @@
@@ -1,60 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" |
||||
package="org.purplei2p.i2pd" |
||||
android:installLocation="auto"> |
||||
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> |
||||
<uses-permission android:name="android.permission.INTERNET" /> |
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> |
||||
<uses-permission android:name="android.permission.READ_PHONE_STATE" /> |
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> |
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> |
||||
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" /> |
||||
|
||||
<application |
||||
android:allowBackup="true" |
||||
android:icon="@drawable/icon" |
||||
android:label="@string/app_name" |
||||
android:requestLegacyExternalStorage="true" |
||||
android:theme="@android:style/Theme.Holo.Light.DarkActionBar" |
||||
android:usesCleartextTraffic="true"> |
||||
<meta-data |
||||
android:name="android.webkit.WebView.MetricsOptOut" |
||||
android:value="true"/> |
||||
|
||||
<activity android:name=".WebConsoleActivity"></activity> |
||||
|
||||
<receiver android:name=".NetworkStateChangeReceiver"> |
||||
<intent-filter> |
||||
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" /> |
||||
</intent-filter> |
||||
</receiver> |
||||
|
||||
<activity |
||||
android:name=".I2PDPermsAskerActivity" |
||||
android:label="@string/app_name"> |
||||
<intent-filter> |
||||
<action android:name="android.intent.action.MAIN" /> |
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" /> |
||||
</intent-filter> |
||||
</activity> |
||||
<activity |
||||
android:name=".I2PDActivity" |
||||
android:label="@string/app_name" /> |
||||
|
||||
<service |
||||
android:name=".ForegroundService" |
||||
android:enabled="true" /> |
||||
|
||||
<activity |
||||
android:name=".I2PDPermsExplanationActivity" |
||||
android:label="@string/title_activity_i2_pdperms_asker_prompt" |
||||
android:parentActivityName=".I2PDPermsAskerActivity"> |
||||
<meta-data |
||||
android:name="android.support.PARENT_ACTIVITY" |
||||
android:value="org.purplei2p.i2pd.I2PDPermsAskerActivity" /> |
||||
</activity> |
||||
</application> |
||||
|
||||
</manifest> |
@ -1,19 +0,0 @@
@@ -1,19 +0,0 @@
|
||||
# how to compile? |
||||
## Install the gradle + NDK or use android-studio |
||||
[https://gradle.org/install/](https://gradle.org/install/) |
||||
|
||||
## Install the depencies |
||||
``` |
||||
git clone https://github.com/PurpleI2P/Boost-for-Android-Prebuilt.git -b boost-1_72_0 |
||||
git clone https://github.com/PurpleI2P/android-ifaddrs.git |
||||
git clone https://github.com/PurpleI2P/OpenSSL-for-Android-Prebuilt.git |
||||
git clone https://github.com/PurpleI2P/MiniUPnP-for-Android-Prebuilt.git |
||||
``` |
||||
## Set libs in jni/Application.mk on 24 line: |
||||
``` |
||||
# change to your own |
||||
I2PD_LIBS_PATH = /home/user/i2pd/android/ |
||||
``` |
||||
|
||||
## compile apk file |
||||
gradle clean assembleRelease |
|
@ -1 +0,0 @@
@@ -1 +0,0 @@
|
||||
../../contrib/certificates |
@ -1,92 +0,0 @@
@@ -1,92 +0,0 @@
|
||||
## Configuration file for a typical i2pd user |
||||
## See https://i2pd.readthedocs.io/en/latest/user-guide/configuration/ |
||||
## for more options you can use in this file. |
||||
|
||||
#logfile = /sdcard/i2pd/i2pd.log |
||||
loglevel = none |
||||
#tunnelsdir = /sdcard/i2pd/tunnels.d |
||||
|
||||
# host = 1.2.3.4 |
||||
# port = 4567 |
||||
|
||||
ipv4 = true |
||||
ipv6 = false |
||||
|
||||
# ntcp = true |
||||
# ntcpproxy = http://127.0.0.1:8118 |
||||
# ssu = true |
||||
|
||||
bandwidth = L |
||||
# share = 100 |
||||
|
||||
# notransit = true |
||||
# floodfill = true |
||||
|
||||
[ntcp2] |
||||
enabled = true |
||||
|
||||
[http] |
||||
enabled = true |
||||
address = 127.0.0.1 |
||||
port = 7070 |
||||
# auth = true |
||||
# user = i2pd |
||||
# pass = changeme |
||||
|
||||
[httpproxy] |
||||
enabled = true |
||||
address = 127.0.0.1 |
||||
port = 4444 |
||||
inbound.length = 1 |
||||
inbound.quantity = 5 |
||||
outbound.length = 1 |
||||
outbound.quantity = 5 |
||||
signaturetype=7 |
||||
i2cp.leaseSetType=3 |
||||
i2cp.leaseSetEncType=0,4 |
||||
keys = proxy-keys.dat |
||||
# addresshelper = true |
||||
# outproxy = http://false.i2p |
||||
## httpproxy section also accepts I2CP parameters, like "inbound.length" etc. |
||||
|
||||
[socksproxy] |
||||
enabled = true |
||||
address = 127.0.0.1 |
||||
port = 4447 |
||||
keys = proxy-keys.dat |
||||
# outproxy.enabled = false |
||||
# outproxy = 127.0.0.1 |
||||
# outproxyport = 9050 |
||||
## socksproxy section also accepts I2CP parameters, like "inbound.length" etc. |
||||
|
||||
[sam] |
||||
enabled = false |
||||
# address = 127.0.0.1 |
||||
# port = 7656 |
||||
|
||||
[precomputation] |
||||
elgamal = true |
||||
|
||||
[upnp] |
||||
enabled = true |
||||
# name = I2Pd |
||||
|
||||
[reseed] |
||||
verify = true |
||||
## Path to local reseed data file (.su3) for manual reseeding |
||||
# file = /path/to/i2pseeds.su3 |
||||
## or HTTPS URL to reseed from |
||||
# file = https://legit-website.com/i2pseeds.su3 |
||||
## Path to local ZIP file or HTTPS URL to reseed from |
||||
# zipfile = /path/to/netDb.zip |
||||
## If you run i2pd behind a proxy server, set proxy server for reseeding here |
||||
## Should be http://address:port or socks://address:port |
||||
# proxy = http://127.0.0.1:8118 |
||||
## Minimum number of known routers, below which i2pd triggers reseeding. 25 by default |
||||
# threshold = 25 |
||||
|
||||
[limits] |
||||
transittunnels = 50 |
||||
|
||||
[persist] |
||||
profiles = false |
@ -1,3 +0,0 @@
@@ -1,3 +0,0 @@
|
||||
http://inr.i2p/export/alive-hosts.txt |
||||
http://stats.i2p/cgi-bin/newhosts.txt |
||||
http://i2p-projekt.i2p/hosts.txt |
@ -1,33 +0,0 @@
@@ -1,33 +0,0 @@
|
||||
#[IRC-IRC2P] |
||||
#type = client |
||||
#address = 127.0.0.1 |
||||
#port = 6668 |
||||
#destination = irc.postman.i2p |
||||
#destinationport = 6667 |
||||
#keys = irc-keys.dat |
||||
|
||||
#[IRC-ILITA] |
||||
#type = client |
||||
#address = 127.0.0.1 |
||||
#port = 6669 |
||||
#destination = irc.ilita.i2p |
||||
#destinationport = 6667 |
||||
#keys = irc-keys.dat |
||||
|
||||
#[SMTP] |
||||
#type = client |
||||
#address = 127.0.0.1 |
||||
#port = 7659 |
||||
#destination = smtp.postman.i2p |
||||
#destinationport = 25 |
||||
#keys = smtp-keys.dat |
||||
|
||||
#[POP3] |
||||
#type = client |
||||
#address = 127.0.0.1 |
||||
#port = 7660 |
||||
#destination = pop.postman.i2p |
||||
#destinationport = 110 |
||||
#keys = pop3-keys.dat |
||||
|
||||
# see more examples at https://i2pd.readthedocs.io/en/latest/user-guide/tunnels/ |
@ -1,105 +0,0 @@
@@ -1,105 +0,0 @@
|
||||
buildscript { |
||||
repositories { |
||||
mavenCentral() |
||||
jcenter() |
||||
google() |
||||
} |
||||
dependencies { |
||||
classpath 'com.android.tools.build:gradle:3.4.2' |
||||
} |
||||
} |
||||
|
||||
apply plugin: 'com.android.application' |
||||
|
||||
repositories { |
||||
jcenter() |
||||
maven { |
||||
url 'https://maven.google.com' |
||||
} |
||||
google() |
||||
} |
||||
|
||||
dependencies { |
||||
implementation 'androidx.core:core:1.0.2' |
||||
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' |
||||
} |
||||
|
||||
android { |
||||
compileSdkVersion 29 |
||||
buildToolsVersion "28.0.3" |
||||
defaultConfig { |
||||
applicationId "org.purplei2p.i2pd" |
||||
targetSdkVersion 29 |
||||
minSdkVersion 14 |
||||
versionCode 2350 |
||||
versionName "2.35.0" |
||||
setProperty("archivesBaseName", archivesBaseName + "-" + versionName) |
||||
ndk { |
||||
abiFilters 'armeabi-v7a' |
||||
abiFilters 'x86' |
||||
//abiFilters 'arm64-v8a' |
||||
//abiFilters 'x86_64' |
||||
} |
||||
externalNativeBuild { |
||||
ndkBuild { |
||||
arguments "-j3" |
||||
} |
||||
} |
||||
} |
||||
sourceSets { |
||||
main { |
||||
manifest.srcFile 'AndroidManifest.xml' |
||||
java.srcDirs = ['src'] |
||||
res.srcDirs = ['res'] |
||||
jniLibs.srcDirs = ['libs'] |
||||
assets.srcDirs = ['assets'] |
||||
} |
||||
} |
||||
splits { |
||||
abi { |
||||
// change that to true if you need splitted apk |
||||
enable true |
||||
reset() |
||||
//include "armeabi-v7a", "arm64-v8a", "x86", "x86_64" |
||||
include "armeabi-v7a", "x86" |
||||
universalApk true |
||||
} |
||||
} |
||||
signingConfigs { |
||||
orignal { |
||||
storeFile file("i2pdapk.jks") |
||||
storePassword "android" |
||||
keyAlias "i2pdapk" |
||||
keyPassword "android" |
||||
} |
||||
} |
||||
buildTypes { |
||||
release { |
||||
minifyEnabled false |
||||
signingConfig signingConfigs.orignal |
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-project.txt' |
||||
} |
||||
} |
||||
externalNativeBuild { |
||||
ndkBuild { |
||||
path './jni/Android.mk' |
||||
} |
||||
} |
||||
compileOptions { |
||||
sourceCompatibility = '1.8' |
||||
targetCompatibility = '1.8' |
||||
} |
||||
} |
||||
|
||||
ext.abiCodes = ['armeabi-v7a': 1, 'x86': 2, 'arm64-v8a': 3, 'x86_64': 4] |
||||
import com.android.build.OutputFile |
||||
|
||||
android.applicationVariants.all { variant -> |
||||
variant.outputs.each { output -> |
||||
def baseAbiVersionCode = project.ext.abiCodes.get(output.getFilter(OutputFile.ABI)) |
||||
|
||||
if (baseAbiVersionCode != null) { |
||||
output.versionCodeOverride = baseAbiVersionCode + variant.versionCode |
||||
} |
||||
} |
||||
} |
@ -1,96 +0,0 @@
@@ -1,96 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<project name="i2pd" default="help"> |
||||
|
||||
<!-- The local.properties file is created and updated by the 'android' tool. |
||||
It contains the path to the SDK. It should *NOT* be checked into |
||||
Version Control Systems. --> |
||||
<property file="local.properties" /> |
||||
|
||||
<!-- The ant.properties file can be created by you. It is only edited by the |
||||
'android' tool to add properties to it. |
||||
This is the place to change some Ant specific build properties. |
||||
Here are some properties you may want to change/update: |
||||
|
||||
source.dir |
||||
The name of the source directory. Default is 'src'. |
||||
out.dir |
||||
The name of the output directory. Default is 'bin'. |
||||
|
||||
For other overridable properties, look at the beginning of the rules |
||||
files in the SDK, at tools/ant/build.xml |
||||
|
||||
Properties related to the SDK location or the project target should |
||||
be updated using the 'android' tool with the 'update' action. |
||||
|
||||
This file is an integral part of the build system for your |
||||
application and should be checked into Version Control Systems. |
||||
|
||||
--> |
||||
<property file="ant.properties" /> |
||||
|
||||
<!-- if sdk.dir was not set from one of the property file, then |
||||
get it from the ANDROID_HOME env var. |
||||
This must be done before we load project.properties since |
||||
the proguard config can use sdk.dir --> |
||||
<property environment="env" /> |
||||
<condition property="sdk.dir" value="${env.ANDROID_HOME}"> |
||||
<isset property="env.ANDROID_HOME" /> |
||||
</condition> |
||||
|
||||
<!-- The project.properties file is created and updated by the 'android' |
||||
tool, as well as ADT. |
||||
|
||||
This contains project specific properties such as project target, and library |
||||
dependencies. Lower level build properties are stored in ant.properties |
||||
(or in .classpath for Eclipse projects). |
||||
|
||||
This file is an integral part of the build system for your |
||||
application and should be checked into Version Control Systems. --> |
||||
<loadproperties srcFile="project.properties" /> |
||||
|
||||
<!-- quick check on sdk.dir --> |
||||
<fail |
||||
message="sdk.dir is missing. Insert sdk.dir=... into './local.properties'. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable." |
||||
unless="sdk.dir" |
||||
/> |
||||
|
||||
<fail |
||||
message="ndk.dir is missing. Insert ndk.dir=... into './local.properties'." |
||||
unless="ndk.dir" |
||||
/> |
||||
|
||||
<!-- |
||||
Import per project custom build rules if present at the root of the project. |
||||
This is the place to put custom intermediary targets such as: |
||||
-pre-build |
||||
-pre-compile |
||||
-post-compile (This is typically used for code obfuscation. |
||||
Compiled code location: ${out.classes.absolute.dir} |
||||
If this is not done in place, override ${out.dex.input.absolute.dir}) |
||||
-post-package |
||||
-post-build |
||||
-pre-clean |
||||
--> |
||||
<import file="custom_rules.xml" optional="true" /> |
||||
|
||||
<!-- Import the actual build file. |
||||
|
||||
To customize existing targets, there are two options: |
||||
- Customize only one target: |
||||
- copy/paste the target into this file, *before* the |
||||
<import> task. |
||||
- customize it to your needs. |
||||
- Customize the whole content of build.xml |
||||
- copy/paste the content of the rules files (minus the top node) |
||||
into this file, replacing the <import> task. |
||||
- customize to your needs. |
||||
|
||||
*********************** |
||||
****** IMPORTANT ****** |
||||
*********************** |
||||
In all cases you must update the value of version-tag below to read 'custom' instead of an integer, |
||||
in order to avoid having your file be overridden by tools such as "android update project" |
||||
--> |
||||
<!-- version-tag: 1 --> |
||||
<import file="${sdk.dir}/tools/ant/build.xml" /> |
||||
</project> |
@ -1,3 +0,0 @@
@@ -1,3 +0,0 @@
|
||||
android.enableJetifier=true |
||||
android.useAndroidX=true |
||||
org.gradle.parallel=true |
@ -1,6 +0,0 @@
@@ -1,6 +0,0 @@
|
||||
#Tue Aug 20 14:39:08 MSK 2019 |
||||
distributionBase=GRADLE_USER_HOME |
||||
distributionPath=wrapper/dists |
||||
zipStoreBase=GRADLE_USER_HOME |
||||
zipStorePath=wrapper/dists |
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip |
@ -1,172 +0,0 @@
@@ -1,172 +0,0 @@
|
||||
#!/usr/bin/env sh |
||||
|
||||
############################################################################## |
||||
## |
||||
## Gradle start up script for UN*X |
||||
## |
||||
############################################################################## |
||||
|
||||
# Attempt to set APP_HOME |
||||
# Resolve links: $0 may be a link |
||||
PRG="$0" |
||||
# Need this for relative symlinks. |
||||
while [ -h "$PRG" ] ; do |
||||
ls=`ls -ld "$PRG"` |
||||
link=`expr "$ls" : '.*-> \(.*\)$'` |
||||
if expr "$link" : '/.*' > /dev/null; then |
||||
PRG="$link" |
||||
else |
||||
PRG=`dirname "$PRG"`"/$link" |
||||
fi |
||||
done |
||||
SAVED="`pwd`" |
||||
cd "`dirname \"$PRG\"`/" >/dev/null |
||||
APP_HOME="`pwd -P`" |
||||
cd "$SAVED" >/dev/null |
||||
|
||||
APP_NAME="Gradle" |
||||
APP_BASE_NAME=`basename "$0"` |
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. |
||||
DEFAULT_JVM_OPTS="" |
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value. |
||||
MAX_FD="maximum" |
||||
|
||||
warn () { |
||||
echo "$*" |
||||
} |
||||
|
||||
die () { |
||||
echo |
||||
echo "$*" |
||||
echo |
||||
exit 1 |
||||
} |
||||
|
||||
# OS specific support (must be 'true' or 'false'). |
||||
cygwin=false |
||||
msys=false |
||||
darwin=false |
||||
nonstop=false |
||||
case "`uname`" in |
||||
CYGWIN* ) |
||||
cygwin=true |
||||
;; |
||||
Darwin* ) |
||||
darwin=true |
||||
;; |
||||
MINGW* ) |
||||
msys=true |
||||
;; |
||||
NONSTOP* ) |
||||
nonstop=true |
||||
;; |
||||
esac |
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar |
||||
|
||||
# Determine the Java command to use to start the JVM. |
||||
if [ -n "$JAVA_HOME" ] ; then |
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then |
||||
# IBM's JDK on AIX uses strange locations for the executables |
||||
JAVACMD="$JAVA_HOME/jre/sh/java" |
||||
else |
||||
JAVACMD="$JAVA_HOME/bin/java" |
||||
fi |
||||
if [ ! -x "$JAVACMD" ] ; then |
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME |
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the |
||||
location of your Java installation." |
||||
fi |
||||
else |
||||
JAVACMD="java" |
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. |
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the |
||||
location of your Java installation." |
||||
fi |
||||
|
||||
# Increase the maximum file descriptors if we can. |
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then |
||||
MAX_FD_LIMIT=`ulimit -H -n` |
||||
if [ $? -eq 0 ] ; then |
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then |
||||
MAX_FD="$MAX_FD_LIMIT" |
||||
fi |
||||
ulimit -n $MAX_FD |
||||
if [ $? -ne 0 ] ; then |
||||
warn "Could not set maximum file descriptor limit: $MAX_FD" |
||||
fi |
||||
else |
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" |
||||
fi |
||||
fi |
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock |
||||
if $darwin; then |
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" |
||||
fi |
||||
|
||||
# For Cygwin, switch paths to Windows format before running java |
||||
if $cygwin ; then |
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"` |
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` |
||||
JAVACMD=`cygpath --unix "$JAVACMD"` |
||||
|
||||
# We build the pattern for arguments to be converted via cygpath |
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` |
||||
SEP="" |
||||
for dir in $ROOTDIRSRAW ; do |
||||
ROOTDIRS="$ROOTDIRS$SEP$dir" |
||||
SEP="|" |
||||
done |
||||
OURCYGPATTERN="(^($ROOTDIRS))" |
||||
# Add a user-defined pattern to the cygpath arguments |
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then |
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" |
||||
fi |
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh |
||||
i=0 |
||||
for arg in "$@" ; do |
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` |
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option |
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition |
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` |
||||
else |
||||
eval `echo args$i`="\"$arg\"" |
||||
fi |
||||
i=$((i+1)) |
||||
done |
||||
case $i in |
||||
(0) set -- ;; |
||||
(1) set -- "$args0" ;; |
||||
(2) set -- "$args0" "$args1" ;; |
||||
(3) set -- "$args0" "$args1" "$args2" ;; |
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;; |
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; |
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; |
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; |
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; |
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; |
||||
esac |
||||
fi |
||||
|
||||
# Escape application args |
||||
save () { |
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done |
||||
echo " " |
||||
} |
||||
APP_ARGS=$(save "$@") |
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules |
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" |
||||
|
||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong |
||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then |
||||
cd "$(dirname "$0")" |
||||
fi |
||||
|
||||
exec "$JAVACMD" "$@" |
@ -1,84 +0,0 @@
@@ -1,84 +0,0 @@
|
||||
@if "%DEBUG%" == "" @echo off |
||||
@rem ########################################################################## |
||||
@rem |
||||
@rem Gradle startup script for Windows |
||||
@rem |
||||
@rem ########################################################################## |
||||
|
||||
@rem Set local scope for the variables with windows NT shell |
||||
if "%OS%"=="Windows_NT" setlocal |
||||
|
||||
set DIRNAME=%~dp0 |
||||
if "%DIRNAME%" == "" set DIRNAME=. |
||||
set APP_BASE_NAME=%~n0 |
||||
set APP_HOME=%DIRNAME% |
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. |
||||
set DEFAULT_JVM_OPTS= |
||||
|
||||
@rem Find java.exe |
||||
if defined JAVA_HOME goto findJavaFromJavaHome |
||||
|
||||
set JAVA_EXE=java.exe |
||||
%JAVA_EXE% -version >NUL 2>&1 |
||||
if "%ERRORLEVEL%" == "0" goto init |
||||
|
||||
echo. |
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. |
||||
echo. |
||||
echo Please set the JAVA_HOME variable in your environment to match the |
||||
echo location of your Java installation. |
||||
|
||||
goto fail |
||||
|
||||
:findJavaFromJavaHome |
||||
set JAVA_HOME=%JAVA_HOME:"=% |
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe |
||||
|
||||
if exist "%JAVA_EXE%" goto init |
||||
|
||||
echo. |
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% |
||||
echo. |
||||
echo Please set the JAVA_HOME variable in your environment to match the |
||||
echo location of your Java installation. |
||||
|
||||
goto fail |
||||
|
||||
:init |
||||
@rem Get command-line arguments, handling Windows variants |
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args |
||||
|
||||
:win9xME_args |
||||
@rem Slurp the command line arguments. |
||||
set CMD_LINE_ARGS= |
||||
set _SKIP=2 |
||||
|
||||
:win9xME_args_slurp |
||||
if "x%~1" == "x" goto execute |
||||
|
||||
set CMD_LINE_ARGS=%* |
||||
|
||||
:execute |
||||
@rem Setup the command line |
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar |
||||
|
||||
@rem Execute Gradle |
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% |
||||
|
||||
:end |
||||
@rem End local scope for the variables with windows NT shell |
||||
if "%ERRORLEVEL%"=="0" goto mainEnd |
||||
|
||||
:fail |
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of |
||||
rem the _cmd.exe /c_ return code! |
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 |
||||
exit /b 1 |
||||
|
||||
:mainEnd |
||||
if "%OS%"=="Windows_NT" endlocal |
||||
|
||||
:omega |
@ -1,73 +0,0 @@
@@ -1,73 +0,0 @@
|
||||
LOCAL_PATH := $(call my-dir) |
||||
include $(CLEAR_VARS) |
||||
LOCAL_MODULE := i2pd |
||||
LOCAL_CPP_FEATURES := rtti exceptions |
||||
LOCAL_C_INCLUDES += $(IFADDRS_PATH) $(LIB_SRC_PATH) $(LIB_CLIENT_SRC_PATH) $(DAEMON_SRC_PATH) |
||||
LOCAL_STATIC_LIBRARIES := \
|
||||
boost_system \
|
||||
boost_date_time \
|
||||
boost_filesystem \
|
||||
boost_program_options \
|
||||
crypto ssl \
|
||||
miniupnpc |
||||
LOCAL_LDLIBS := -lz |
||||
|
||||
LOCAL_SRC_FILES := DaemonAndroid.cpp i2pd_android.cpp $(IFADDRS_PATH)/ifaddrs.c \
|
||||
$(wildcard $(LIB_SRC_PATH)/*.cpp)\
|
||||
$(wildcard $(LIB_CLIENT_SRC_PATH)/*.cpp)\
|
||||
$(DAEMON_SRC_PATH)/Daemon.cpp \
|
||||
$(DAEMON_SRC_PATH)/UPnP.cpp \
|
||||
$(DAEMON_SRC_PATH)/HTTPServer.cpp \
|
||||
$(DAEMON_SRC_PATH)/I2PControl.cpp |
||||
|
||||
include $(BUILD_SHARED_LIBRARY) |
||||
|
||||
LOCAL_PATH := $(call my-dir) |
||||
include $(CLEAR_VARS) |
||||
LOCAL_MODULE := boost_system |
||||
LOCAL_SRC_FILES := $(BOOST_PATH)/boost-1_72_0/$(TARGET_ARCH_ABI)/lib/libboost_system.a |
||||
LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost-1_72_0/include |
||||
include $(PREBUILT_STATIC_LIBRARY) |
||||
|
||||
LOCAL_PATH := $(call my-dir) |
||||
include $(CLEAR_VARS) |
||||
LOCAL_MODULE := boost_date_time |
||||
LOCAL_SRC_FILES := $(BOOST_PATH)/boost-1_72_0/$(TARGET_ARCH_ABI)/lib/libboost_date_time.a |
||||
LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost-1_72_0/include |
||||
include $(PREBUILT_STATIC_LIBRARY) |
||||
|
||||
LOCAL_PATH := $(call my-dir) |
||||
include $(CLEAR_VARS) |
||||
LOCAL_MODULE := boost_filesystem |
||||
LOCAL_SRC_FILES := $(BOOST_PATH)/boost-1_72_0/$(TARGET_ARCH_ABI)/lib/libboost_filesystem.a |
||||
LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost-1_72_0/include |
||||
include $(PREBUILT_STATIC_LIBRARY) |
||||
|
||||
LOCAL_PATH := $(call my-dir) |
||||
include $(CLEAR_VARS) |
||||
LOCAL_MODULE := boost_program_options |
||||
LOCAL_SRC_FILES := $(BOOST_PATH)/boost-1_72_0/$(TARGET_ARCH_ABI)/lib/libboost_program_options.a |
||||
LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost-1_72_0/include |
||||
include $(PREBUILT_STATIC_LIBRARY) |
||||
|
||||
LOCAL_PATH := $(call my-dir) |
||||
include $(CLEAR_VARS) |
||||
LOCAL_MODULE := crypto |
||||
LOCAL_SRC_FILES := $(OPENSSL_PATH)/openssl-1.1.1d-clang/$(TARGET_ARCH_ABI)/lib/libcrypto.a |
||||
LOCAL_EXPORT_C_INCLUDES := $(OPENSSL_PATH)/openssl-1.1.1d-clang/include |
||||
include $(PREBUILT_STATIC_LIBRARY) |
||||
|
||||
LOCAL_PATH := $(call my-dir) |
||||
include $(CLEAR_VARS) |
||||
LOCAL_MODULE := ssl |
||||
LOCAL_SRC_FILES := $(OPENSSL_PATH)/openssl-1.1.1d-clang/$(TARGET_ARCH_ABI)/lib/libssl.a |
||||
LOCAL_EXPORT_C_INCLUDES := $(OPENSSL_PATH)/openssl-1.1.1d-clang/include |
||||
LOCAL_STATIC_LIBRARIES := crypto |
||||
include $(PREBUILT_STATIC_LIBRARY) |
||||
|
||||
LOCAL_PATH := $(call my-dir) |
||||
include $(CLEAR_VARS) |
||||
LOCAL_MODULE := miniupnpc |
||||
LOCAL_SRC_FILES := $(MINIUPNP_PATH)/miniupnpc-2.1/$(TARGET_ARCH_ABI)/lib/libminiupnpc.a |
||||
LOCAL_EXPORT_C_INCLUDES := $(MINIUPNP_PATH)/miniupnpc-2.1/include |
||||
include $(PREBUILT_STATIC_LIBRARY) |
@ -1,36 +0,0 @@
@@ -1,36 +0,0 @@
|
||||
#APP_ABI := armeabi-v7a x86
|
||||
#APP_PLATFORM := android-14
|
||||
|
||||
# ABI arm64-v8a and x86_64 supported only from platform-21
|
||||
#APP_ABI := arm64-v8a x86_64
|
||||
#APP_PLATFORM := android-21
|
||||
|
||||
NDK_TOOLCHAIN_VERSION := clang |
||||
#APP_STL := c++_shared
|
||||
APP_STL := c++_static |
||||
|
||||
# Enable c++17 extensions in source code
|
||||
APP_CPPFLAGS += -std=c++17 -fexceptions -frtti |
||||
|
||||
APP_CPPFLAGS += -DANDROID -D__ANDROID__ -DUSE_UPNP |
||||
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) |
||||
APP_CPPFLAGS += -DANDROID_ARM7A |
||||
endif |
||||
|
||||
# git clone https://github.com/PurpleI2P/Boost-for-Android-Prebuilt.git -b boost-1_72_0
|
||||
# git clone https://github.com/PurpleI2P/OpenSSL-for-Android-Prebuilt.git
|
||||
# git clone https://github.com/PurpleI2P/MiniUPnP-for-Android-Prebuilt.git
|
||||
# git clone https://github.com/PurpleI2P/android-ifaddrs.git
|
||||
# change to your own
|
||||
I2PD_LIBS_PATH = /path/to/libraries |
||||
BOOST_PATH = $(I2PD_LIBS_PATH)/Boost-for-Android-Prebuilt |
||||
OPENSSL_PATH = $(I2PD_LIBS_PATH)/OpenSSL-for-Android-Prebuilt |
||||
MINIUPNP_PATH = $(I2PD_LIBS_PATH)/MiniUPnP-for-Android-Prebuilt |
||||
IFADDRS_PATH = $(I2PD_LIBS_PATH)/android-ifaddrs |
||||
|
||||
# don't change me
|
||||
I2PD_SRC_PATH = $(PWD)/.. |
||||
|
||||
LIB_SRC_PATH = $(I2PD_SRC_PATH)/libi2pd |
||||
LIB_CLIENT_SRC_PATH = $(I2PD_SRC_PATH)/libi2pd_client |
||||
DAEMON_SRC_PATH = $(I2PD_SRC_PATH)/daemon |
@ -1,222 +0,0 @@
@@ -1,222 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2020, The PurpleI2P Project |
||||
* |
||||
* This file is part of Purple i2pd project and licensed under BSD3 |
||||
* |
||||
* See full license text in LICENSE file at top of project tree |
||||
*/ |
||||
|
||||
#include <iostream> |
||||
#include <chrono> |
||||
#include <thread> |
||||
#include <exception> |
||||
#include <boost/exception/diagnostic_information.hpp> |
||||
#include <boost/exception_ptr.hpp> |
||||
//#include "mainwindow.h"
|
||||
#include "FS.h" |
||||
#include "DaemonAndroid.h" |
||||
#include "Daemon.h" |
||||
|
||||
namespace i2p |
||||
{ |
||||
namespace android |
||||
{ |
||||
/* Worker::Worker (DaemonAndroidImpl& daemon):
|
||||
m_Daemon (daemon) |
||||
{ |
||||
} |
||||
|
||||
void Worker::startDaemon() |
||||
{ |
||||
Log.d(TAG"Performing daemon start..."); |
||||
m_Daemon.start(); |
||||
Log.d(TAG"Daemon started."); |
||||
emit resultReady(); |
||||
} |
||||
void Worker::restartDaemon() |
||||
{ |
||||
Log.d(TAG"Performing daemon restart..."); |
||||
m_Daemon.restart(); |
||||
Log.d(TAG"Daemon restarted."); |
||||
emit resultReady(); |
||||
} |
||||
void Worker::stopDaemon() { |
||||
Log.d(TAG"Performing daemon stop..."); |
||||
m_Daemon.stop(); |
||||
Log.d(TAG"Daemon stopped."); |
||||
emit resultReady(); |
||||
} |
||||
|
||||
Controller::Controller(DaemonAndroidImpl& daemon): |
||||
m_Daemon (daemon) |
||||
{ |
||||
Worker *worker = new Worker (m_Daemon); |
||||
worker->moveToThread(&workerThread); |
||||
connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater); |
||||
connect(this, &Controller::startDaemon, worker, &Worker::startDaemon); |
||||
connect(this, &Controller::stopDaemon, worker, &Worker::stopDaemon); |
||||
connect(this, &Controller::restartDaemon, worker, &Worker::restartDaemon); |
||||
connect(worker, &Worker::resultReady, this, &Controller::handleResults); |
||||
workerThread.start(); |
||||
} |
||||
Controller::~Controller() |
||||
{ |
||||
Log.d(TAG"Closing and waiting for daemon worker thread..."); |
||||
workerThread.quit(); |
||||
workerThread.wait(); |
||||
Log.d(TAG"Waiting for daemon worker thread finished."); |
||||
if(m_Daemon.isRunning()) |
||||
{ |
||||
Log.d(TAG"Stopping the daemon..."); |
||||
m_Daemon.stop(); |
||||
Log.d(TAG"Stopped the daemon."); |
||||
} |
||||
} |
||||
*/ |
||||
std::string dataDir = ""; |
||||
|
||||
DaemonAndroidImpl::DaemonAndroidImpl () |
||||
//:
|
||||
/*mutex(nullptr), */ |
||||
//m_IsRunning(false),
|
||||
//m_RunningChangedCallback(nullptr)
|
||||
{ |
||||
} |
||||
|
||||
DaemonAndroidImpl::~DaemonAndroidImpl () |
||||
{ |
||||
//delete mutex;
|
||||
} |
||||
|
||||
bool DaemonAndroidImpl::init(int argc, char* argv[]) |
||||
{ |
||||
//mutex=new QMutex(QMutex::Recursive);
|
||||
//setRunningCallback(0);
|
||||
//m_IsRunning=false;
|
||||
|
||||
// make sure assets are ready before proceed
|
||||
i2p::fs::DetectDataDir(dataDir, false); |
||||
int numAttempts = 0; |
||||
do |
||||
{ |
||||
if (i2p::fs::Exists (i2p::fs::DataDirPath("assets.ready"))) break; // assets ready
|
||||
numAttempts++; |
||||
std::this_thread::sleep_for (std::chrono::seconds(1)); // otherwise wait for 1 more second
|
||||
} |
||||
while (numAttempts <= 10); // 10 seconds max
|
||||
return Daemon.init(argc,argv); |
||||
} |
||||
|
||||
void DaemonAndroidImpl::start() |
||||
{ |
||||
//QMutexLocker locker(mutex);
|
||||
//setRunning(true);
|
||||
Daemon.start(); |
||||
} |
||||
|
||||
void DaemonAndroidImpl::stop() |
||||
{ |
||||
//QMutexLocker locker(mutex);
|
||||
Daemon.stop(); |
||||
//setRunning(false);
|
||||
} |
||||
|
||||
void DaemonAndroidImpl::restart() |
||||
{ |
||||
//QMutexLocker locker(mutex);
|
||||
stop(); |
||||
start(); |
||||
} |
||||
/*
|
||||
void DaemonAndroidImpl::setRunningCallback(runningChangedCallback cb) |
||||
{ |
||||
m_RunningChangedCallback = cb; |
||||
} |
||||
|
||||
bool DaemonAndroidImpl::isRunning() |
||||
{ |
||||
return m_IsRunning; |
||||
} |
||||
|
||||
void DaemonAndroidImpl::setRunning(bool newValue) |
||||
{ |
||||
bool oldValue = m_IsRunning; |
||||
if(oldValue!=newValue) |
||||
{ |
||||
m_IsRunning = newValue; |
||||
if(m_RunningChangedCallback) |
||||
m_RunningChangedCallback(); |
||||
} |
||||
} |
||||
*/ |
||||
static DaemonAndroidImpl daemon; |
||||
static char* argv[1]={strdup("tmp")}; |
||||
/**
|
||||
* returns error details if failed |
||||
* returns "ok" if daemon initialized and started okay |
||||
*/ |
||||
std::string start(/*int argc, char* argv[]*/) |
||||
{ |
||||
try |
||||
{ |
||||
//int result;
|
||||
|
||||
{ |
||||
//Log.d(TAG"Initialising the daemon...");
|
||||
bool daemonInitSuccess = daemon.init(1,argv); |
||||
if(!daemonInitSuccess) |
||||
{ |
||||
//QMessageBox::critical(0, "Error", "Daemon init failed");
|
||||
return "Daemon init failed"; |
||||
} |
||||
//Log.d(TAG"Initialised, creating the main window...");
|
||||
//MainWindow w;
|
||||
//Log.d(TAG"Before main window.show()...");
|
||||
//w.show ();
|
||||
|
||||
{ |
||||
//i2p::qt::Controller daemonQtController(daemon);
|
||||
//Log.d(TAG"Starting the daemon...");
|
||||
//emit daemonQtController.startDaemon();
|
||||
//daemon.start ();
|
||||
//Log.d(TAG"Starting GUI event loop...");
|
||||
//result = app.exec();
|
||||
//daemon.stop ();
|
||||
daemon.start(); |
||||
} |
||||
} |
||||
|
||||
//QMessageBox::information(&w, "Debug", "demon stopped");
|
||||
//Log.d(TAG"Exiting the application");
|
||||
//return result;
|
||||
} |
||||
catch (boost::exception& ex) |
||||
{ |
||||
std::stringstream ss; |
||||
ss << boost::diagnostic_information(ex); |
||||
return ss.str(); |
||||
} |
||||
catch (std::exception& ex) |
||||
{ |
||||
std::stringstream ss; |
||||
ss << ex.what(); |
||||
return ss.str(); |
||||
} |
||||
catch(...) |
||||
{ |
||||
return "unknown exception"; |
||||
} |
||||
return "ok"; |
||||
} |
||||
|
||||
void stop() |
||||
{ |
||||
daemon.stop(); |
||||
} |
||||
|
||||
void SetDataDir(std::string jdataDir) |
||||
{ |
||||
dataDir = jdataDir; |
||||
} |
||||
} |
||||
} |
@ -1,97 +0,0 @@
@@ -1,97 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2020, The PurpleI2P Project |
||||
* |
||||
* This file is part of Purple i2pd project and licensed under BSD3 |
||||
* |
||||
* See full license text in LICENSE file at top of project tree |
||||
*/ |
||||
|
||||
#ifndef DAEMON_ANDROID_H |
||||
#define DAEMON_ANDROID_H |
||||
|
||||
#include <string> |
||||
|
||||
namespace i2p |
||||
{ |
||||
namespace android |
||||
{ |
||||
class DaemonAndroidImpl |
||||
{ |
||||
public: |
||||
|
||||
DaemonAndroidImpl (); |
||||
~DaemonAndroidImpl (); |
||||
|
||||
//typedef void (*runningChangedCallback)();
|
||||
|
||||
/**
|
||||
* @return success |
||||
*/ |
||||
bool init(int argc, char* argv[]); |
||||
void start(); |
||||
void stop(); |
||||
void restart(); |
||||
//void setRunningCallback(runningChangedCallback cb);
|
||||
//bool isRunning();
|
||||
private: |
||||
//void setRunning(bool running);
|
||||
private: |
||||
//QMutex* mutex;
|
||||
//bool m_IsRunning;
|
||||
//runningChangedCallback m_RunningChangedCallback;
|
||||
}; |
||||
|
||||
/**
|
||||
* returns "ok" if daemon init failed |
||||
* returns errinfo if daemon initialized and started okay |
||||
*/ |
||||
std::string start(); |
||||
|
||||
// stops the daemon
|
||||
void stop(); |
||||
|
||||
// set datadir received from jni
|
||||
void SetDataDir(std::string jdataDir); |
||||
/*
|
||||
class Worker : public QObject |
||||
{ |
||||
Q_OBJECT |
||||
public: |
||||
|
||||
Worker (DaemonAndroidImpl& daemon); |
||||
|
||||
private: |
||||
|
||||
DaemonAndroidImpl& m_Daemon; |
||||
|
||||
public slots: |
||||
void startDaemon(); |
||||
void restartDaemon(); |
||||
void stopDaemon(); |
||||
|
||||
signals: |
||||
void resultReady(); |
||||
}; |
||||
|
||||
class Controller : public QObject |
||||
{ |
||||
Q_OBJECT |
||||
QThread workerThread; |
||||
public: |
||||
Controller(DaemonAndroidImpl& daemon); |
||||
~Controller(); |
||||
private: |
||||
DaemonAndroidImpl& m_Daemon; |
||||
|
||||
public slots: |
||||
void handleResults(){} |
||||
signals: |
||||
void startDaemon(); |
||||
void stopDaemon(); |
||||
void restartDaemon(); |
||||
}; |
||||
*/ |
||||
} |
||||
} |
||||
|
||||
#endif // DAEMON_ANDROID_H
|
@ -1,114 +0,0 @@
@@ -1,114 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2020, The PurpleI2P Project |
||||
* |
||||
* This file is part of Purple i2pd project and licensed under BSD3 |
||||
* |
||||
* See full license text in LICENSE file at top of project tree |
||||
*/ |
||||
|
||||
#include <jni.h> |
||||
#include "org_purplei2p_i2pd_I2PD_JNI.h" |
||||
#include "DaemonAndroid.h" |
||||
#include "RouterContext.h" |
||||
#include "ClientContext.h" |
||||
#include "Transports.h" |
||||
#include "Tunnel.h" |
||||
|
||||
JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_getABICompiledWith |
||||
(JNIEnv *env, jclass clazz) { |
||||
#if defined(__arm__) |
||||
#if defined(__ARM_ARCH_7A__) |
||||
#if defined(__ARM_NEON__) |
||||
#if defined(__ARM_PCS_VFP) |
||||
#define ABI "armeabi-v7a/NEON (hard-float)" |
||||
#else |
||||
#define ABI "armeabi-v7a/NEON" |
||||
#endif |
||||
#else |
||||
#if defined(__ARM_PCS_VFP) |
||||
#define ABI "armeabi-v7a (hard-float)" |
||||
#else |
||||
#define ABI "armeabi-v7a" |
||||
#endif |
||||
#endif |
||||
#else |
||||
#define ABI "armeabi" |
||||
#endif |
||||
#elif defined(__i386__) |
||||
#define ABI "x86" |
||||
#elif defined(__x86_64__) |
||||
#define ABI "x86_64" |
||||
#elif defined(__mips64) /* mips64el-* toolchain defines __mips__ too */ |
||||
#define ABI "mips64" |
||||
#elif defined(__mips__) |
||||
#define ABI "mips" |
||||
#elif defined(__aarch64__) |
||||
#define ABI "arm64-v8a" |
||||
#else |
||||
#define ABI "unknown" |
||||
#endif |
||||
|
||||
return env->NewStringUTF(ABI); |
||||
} |
||||
|
||||
JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_startDaemon |
||||
(JNIEnv *env, jclass clazz) { |
||||
return env->NewStringUTF(i2p::android::start().c_str()); |
||||
} |
||||
|
||||
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_stopDaemon |
||||
(JNIEnv *env, jclass clazz) { |
||||
i2p::android::stop(); |
||||
} |
||||
|
||||
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_stopAcceptingTunnels |
||||
(JNIEnv *env, jclass clazz) { |
||||
i2p::context.SetAcceptsTunnels (false); |
||||
} |
||||
|
||||
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_startAcceptingTunnels |
||||
(JNIEnv *env, jclass clazz) { |
||||
i2p::context.SetAcceptsTunnels (true); |
||||
} |
||||
|
||||
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_reloadTunnelsConfigs |
||||
(JNIEnv *env, jclass clazz) { |
||||
i2p::client::context.ReloadConfig(); |
||||
} |
||||
|
||||
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_onNetworkStateChanged |
||||
(JNIEnv *env, jclass clazz, jboolean isConnected) { |
||||
bool isConnectedBool = (bool) isConnected; |
||||
i2p::transport::transports.SetOnline (isConnectedBool); |
||||
} |
||||
|
||||
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_setDataDir |
||||
(JNIEnv *env, jclass clazz, jstring jdataDir) { |
||||
|
||||
/*
|
||||
// Method 1: convert UTF-16 jstring to std::string (https://stackoverflow.com/a/41820336)
|
||||
const jclass stringClass = env->GetObjectClass(jdataDir); |
||||
const jmethodID getBytes = env->GetMethodID(stringClass, "getBytes", "(Ljava/lang/String;)[B"); |
||||
const jbyteArray stringJbytes = (jbyteArray) env->CallObjectMethod(jdataDir, getBytes, env->NewStringUTF("UTF-8")); |
||||
|
||||
size_t length = (size_t) env->GetArrayLength(stringJbytes); |
||||
jbyte* pBytes = env->GetByteArrayElements(stringJbytes, NULL); |
||||
|
||||
std::string dataDir = std::string((char *)pBytes, length); |
||||
env->ReleaseByteArrayElements(stringJbytes, pBytes, JNI_ABORT); |
||||
|
||||
env->DeleteLocalRef(stringJbytes); |
||||
env->DeleteLocalRef(stringClass); */ |
||||
|
||||
// Method 2: get string chars and make char array.
|
||||
auto dataDir = env->GetStringUTFChars(jdataDir, NULL); |
||||
env->ReleaseStringUTFChars(jdataDir, dataDir); |
||||
|
||||
// Set DataDir
|
||||
i2p::android::SetDataDir(dataDir); |
||||
} |
||||
|
||||
JNIEXPORT jint JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_GetTransitTunnelsCount |
||||
(JNIEnv *env, jclass clazz) { |
||||
return i2p::tunnel::tunnels.CountTransitTunnels(); |
||||
} |
@ -1,53 +0,0 @@
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2020, The PurpleI2P Project |
||||
* |
||||
* This file is part of Purple i2pd project and licensed under BSD3 |
||||
* |
||||
* See full license text in LICENSE file at top of project tree |
||||
*/ |
||||
|
||||
/* DO NOT EDIT THIS FILE - it is machine generated */ |
||||
#include <jni.h> |
||||
/* Header for class org_purplei2p_i2pd_I2PD_JNI */ |
||||
|
||||
#ifndef _Included_org_purplei2p_i2pd_I2PD_JNI |
||||
#define _Included_org_purplei2p_i2pd_I2PD_JNI |
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
/*
|
||||
* Class: org_purplei2p_i2pd_I2PD_JNI |
||||
* Method: stringFromJNI |
||||
* Signature: ()Ljava/lang/String; |
||||
*/ |
||||
JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_getABICompiledWith |
||||
(JNIEnv *, jclass); |
||||
|
||||
JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_startDaemon |
||||
(JNIEnv *, jclass); |
||||
|
||||
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_stopDaemon |
||||
(JNIEnv *, jclass); |
||||
|
||||
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_stopAcceptingTunnels |
||||
(JNIEnv *, jclass); |
||||
|
||||
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_startAcceptingTunnels |
||||
(JNIEnv *, jclass); |
||||
|
||||
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_reloadTunnelsConfigs |
||||
(JNIEnv *, jclass); |
||||
|
||||
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_onNetworkStateChanged |
||||
(JNIEnv * env, jclass clazz, jboolean isConnected); |
||||
|
||||
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_setDataDir |
||||
(JNIEnv *env, jclass clazz, jstring jdataDir); |
||||
|
||||
JNIEXPORT jint JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_GetTransitTunnelsCount |
||||
(JNIEnv *, jclass); |
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
#endif |
@ -1,20 +0,0 @@
@@ -1,20 +0,0 @@
|
||||
# To enable ProGuard in your project, edit project.properties |
||||
# to define the proguard.config property as described in that file. |
||||
# |
||||
# Add project specific ProGuard rules here. |
||||
# By default, the flags in this file are appended to flags specified |
||||
# in ${sdk.dir}/tools/proguard/proguard-android.txt |
||||
# You can edit the include path and order by changing the ProGuard |
||||
# include property in project.properties. |
||||
# |
||||
# For more details, see |
||||
# http://developer.android.com/guide/developing/tools/proguard.html |
||||
|
||||
# Add any project specific keep options here: |
||||
|
||||
# If your project uses WebView with JS, uncomment the following |
||||
# and specify the fully qualified class name to the JavaScript interface |
||||
# class: |
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview { |
||||
# public *; |
||||
#} |
@ -1,14 +0,0 @@
@@ -1,14 +0,0 @@
|
||||
# This file is automatically generated by Android Tools. |
||||
# Do not modify this file -- YOUR CHANGES WILL BE ERASED! |
||||
# |
||||
# This file must be checked in Version Control Systems. |
||||
# |
||||
# To customize properties used by the Ant build system edit |
||||
# "ant.properties", and override values to adapt the script to your |
||||
# project structure. |
||||
# |
||||
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): |
||||
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt |
||||
|
||||
# Project target. |
||||
target=android-29 |
Before Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 1.9 KiB |
@ -1,26 +0,0 @@
@@ -1,26 +0,0 @@
|
||||
<LinearLayout android:id="@+id/main_layout" |
||||
xmlns:android="http://schemas.android.com/apk/res/android" |
||||
xmlns:tools="http://schemas.android.com/tools" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent" |
||||
android:orientation="vertical" |
||||
android:paddingBottom="@dimen/vertical_page_margin" |
||||
android:paddingLeft="@dimen/horizontal_page_margin" |
||||
android:paddingRight="@dimen/horizontal_page_margin" |
||||
android:paddingTop="@dimen/vertical_page_margin" |
||||
tools:context=".I2PDPermsAskerActivity"> |
||||
|
||||
<TextView |
||||
android:id="@+id/textview_retry" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginBottom="@dimen/horizontal_page_margin" |
||||
android:visibility="gone" /> |
||||
|
||||
<Button |
||||
android:id="@+id/button_request_write_ext_storage_perms" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:text="@string/retryPermRequest" |
||||
android:visibility="gone" /> |
||||
</LinearLayout> |
@ -1,25 +0,0 @@
@@ -1,25 +0,0 @@
|
||||
<LinearLayout android:id="@+id/layout_prompt" |
||||
xmlns:android="http://schemas.android.com/apk/res/android" |
||||
xmlns:tools="http://schemas.android.com/tools" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent" |
||||
android:orientation="vertical" |
||||
android:paddingBottom="@dimen/vertical_page_margin" |
||||
android:paddingLeft="@dimen/horizontal_page_margin" |
||||
android:paddingRight="@dimen/horizontal_page_margin" |
||||
android:paddingTop="@dimen/vertical_page_margin" |
||||
tools:context=".I2PDPermsAskerActivity"> |
||||
|
||||
<TextView |
||||
android:id="@+id/textview_explanation" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginBottom="@dimen/horizontal_page_margin" |
||||
android:text="@string/permRequired" /> |
||||
|
||||
<Button |
||||
android:id="@+id/button_ok" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:text="@string/ok" /> |
||||
</LinearLayout> |
@ -1,22 +0,0 @@
@@ -1,22 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<LinearLayout android:id="@+id/layout_prompt" |
||||
xmlns:android="http://schemas.android.com/apk/res/android" |
||||
xmlns:app="http://schemas.android.com/apk/res-auto" |
||||
xmlns:tools="http://schemas.android.com/tools" |
||||
android:layout_width="fill_parent" |
||||
android:layout_height="fill_parent" |
||||
tools:context=".WebConsoleActivity"> |
||||
|
||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout |
||||
android:layout_width="fill_parent" |
||||
android:layout_height="fill_parent" |
||||
android:id="@+id/swipe"> |
||||
|
||||
<WebView |
||||
android:id="@+id/webview1" |
||||
android:layout_width="fill_parent" |
||||
android:layout_height="fill_parent" /> |
||||
|
||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout> |
||||
|
||||
</LinearLayout> |
@ -1,31 +0,0 @@
@@ -1,31 +0,0 @@
|
||||
<menu |
||||
xmlns:android="http://schemas.android.com/apk/res/android" |
||||
xmlns:app="http://schemas.android.com/apk/res-auto" |
||||
xmlns:tools="http://schemas.android.com/tools" |
||||
tools:context=".I2PDActivity"> |
||||
|
||||
<group android:id="@+id/group_various"> |
||||
<item |
||||
android:id="@+id/action_battery_otimizations" |
||||
android:title="@string/menu_item_battery_optimizations_str" /> |
||||
</group> |
||||
|
||||
<group android:id="@+id/group_i2pd_control"> |
||||
<item |
||||
android:id="@+id/action_start_webview" |
||||
android:orderInCategory="96" |
||||
android:title="@string/action_start_webview" /> |
||||
<item |
||||
android:id="@+id/action_reload_tunnels_config" |
||||
android:orderInCategory="97" |
||||
android:title="@string/action_reload_tunnels_config" /> |
||||
<item |
||||
android:id="@+id/action_graceful_stop" |
||||
android:orderInCategory="98" |
||||
android:title="@string/action_graceful_stop" /> |
||||
<item |
||||
android:id="@+id/action_stop" |
||||
android:orderInCategory="99" |
||||
android:title="@string/action_stop" /> |
||||
</group> |
||||
</menu> |
@ -1,40 +0,0 @@
@@ -1,40 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<resources> |
||||
<string name="app_name">i2pd</string> |
||||
|
||||
<string name="action_stop">Остановить</string> |
||||
<string name="action_graceful_stop">Корректная остановка</string> |
||||
<string name="action_cancel_graceful_stop">Отменить корректную остановку</string> |
||||
<string name="action_reload_tunnels_config">Перезагрузить туннели</string> |
||||
<string name="action_start_webview">Открыть Веб Консоль</string> |
||||
|
||||
<string name="graceful_stop_is_already_in_progress">Корректная остановка уже запущена</string> |
||||
<string name="graceful_stop_is_in_progress">Корректная остановка запущена</string> |
||||
<string name="gracefulShutdownInProgress">Корректная остановка запущена</string> |
||||
|
||||
<string name="already_stopped">Уже остановлено</string> |
||||
<string name="uninitialized">Приложение инициализируется</string> |
||||
<string name="starting">Приложение запускается</string> |
||||
<string name="jniLibraryLoaded">Загружены JNI библиотеки</string> |
||||
<string name="startedOkay">Приложение запущено</string> |
||||
<string name="startFailed">Запуск не удался</string> |
||||
<string name="stopped">Приложение было остановлено</string> |
||||
<string name="remaining">осталось</string> |
||||
|
||||
<string name="title_activity_i2_pdperms_asker_prompt">Запрос</string> |
||||
<string name="permDenied">Права для записи на SD карту отклонены, вам необходимо предоставить их для продолжения</string> |
||||
<string name="permRequired">Права на запись на SD карту необходимы для записи ключей и других файлов в папку I2PD на внутренней памяти.</string> |
||||
<string name="retryPermRequest">Повторить запрос прав на запись на SD карту</string> |
||||
|
||||
<string name="menu_item_battery_optimizations_str">Оптимизации аккумулятора</string> |
||||
<string name="battery_optimizations_enabled">Оптимизации аккумулятора включены</string> |
||||
<string name="battery_optimizations_enabled_explained">Ваша операционная система осуществляет оптимизации расхода аккумулятора, которые могут приводить к выгрузке I2PD из памяти и прекращению его работы с целью сэкономить заряд аккумулятора.\nРекомендуется отключить эти оптимизации.</string> |
||||
<string name="battery_optimizations_enabled_dialog">Ваша операционная система осуществляет оптимизации расхода аккумулятора, которые могут приводить к выгрузке I2PD из памяти и прекращению его работы с целью сэкономить заряд аккумулятора.\n\nВам сейчас будет предложено разрешить отключение этих оптимизаций.</string> |
||||
<string name="continue_str">Продолжить</string> |
||||
<string name="device_does_not_support_disabling_battery_optimizations">Ваша версия Андроид не поддерживает отключение оптимизаций аккумулятора</string> |
||||
<string name="os_version_does_not_support_battery_optimizations_show_os_dialog_api">Ваша версия Андроид не поддерживает показ диалога об оптимизациях аккумулятора для приложений.</string> |
||||
|
||||
<string name="shutdown_canceled">Плановая остановка отменена</string> |
||||
|
||||
<string name="tunnels_reloading">Перезагрузка конфигурации туннелей...</string> |
||||
</resources> |
@ -1,41 +0,0 @@
@@ -1,41 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation"> |
||||
<string name="app_name">i2pd</string> |
||||
|
||||
<string name="action_stop">Stop</string> |
||||
<string name="action_graceful_stop">Graceful Stop</string> |
||||
<string name="action_cancel_graceful_stop">Cancel Graceful Stop</string> |
||||
<string name="action_reload_tunnels_config">Reload tunnels</string> |
||||
<string name="action_start_webview">Open Web Console</string> |
||||
|
||||
<string name="graceful_stop_is_already_in_progress">Graceful stop is already in progress</string> |
||||
<string name="graceful_stop_is_in_progress">Graceful stop is in progress</string> |
||||
<string name="gracefulShutdownInProgress">Graceful shutdown in progress</string> |
||||
|
||||
<string name="already_stopped">Already stopped</string> |
||||
<string name="uninitialized">Application initializing</string> |
||||
<string name="starting">Application starting</string> |
||||
<string name="jniLibraryLoaded">Loaded JNI libraries</string> |
||||
<string name="startedOkay">Application Started</string> |
||||
<string name="startFailed">Start failed</string> |
||||
<string name="stopped">Application stopped</string> |
||||
<string name="remaining">remaining</string> |
||||
<string name="ok">OK</string> |
||||
|
||||
<string name="title_activity_i2_pdperms_asker_prompt">Prompt</string> |
||||
<string name="permDenied">SD card write permission denied, you need to allow this to continue</string> |
||||
<string name="permRequired">SD card write access is required to write the keys and other files to the I2PD folder on SD card.</string> |
||||
<string name="retryPermRequest">Retry requesting the SD card write permissions</string> |
||||
|
||||
<string name="menu_item_battery_optimizations_str">Battery Optimizations</string> |
||||
<string name="battery_optimizations_enabled">Battery optimizations enabled</string> |
||||
<string name="battery_optimizations_enabled_explained">Your Android is doing some heavy battery optimizations on I2PD that might lead to daemon closing with no other reason.\nIt is recommended to allow disabling those battery optimizations.</string> |
||||
<string name="battery_optimizations_enabled_dialog">Your Android is doing some heavy battery optimizations on I2PD that might lead to daemon closing with no other reason.\n\nYou will now be asked to allow to disable those.</string> |
||||
<string name="continue_str">Continue</string> |
||||
<string name="device_does_not_support_disabling_battery_optimizations">Your Android version does not support opting out of battery optimizations</string> |
||||
<string name="os_version_does_not_support_battery_optimizations_show_os_dialog_api">Your Android OS version does not support showing the dialog for battery optimizations for applications.</string> |
||||
|
||||
<string name="shutdown_canceled">Planned shutdown canceled</string> |
||||
|
||||
<string name="tunnels_reloading">Reloading tunnels config...</string> |
||||
</resources> |
@ -1,16 +0,0 @@
@@ -1,16 +0,0 @@
|
||||
<resources> |
||||
|
||||
<!-- Define standard dimensions to comply with Holo-style grids and rhythm. --> |
||||
|
||||
<dimen name="margin_tiny">4dp</dimen> |
||||
<dimen name="margin_small">8dp</dimen> |
||||
<dimen name="margin_medium">16dp</dimen> |
||||
<dimen name="margin_large">32dp</dimen> |
||||
<dimen name="margin_huge">64dp</dimen> |
||||
|
||||
<!-- Semantic definitions --> |
||||
|
||||
<dimen name="horizontal_page_margin">@dimen/margin_medium</dimen> |
||||
<dimen name="vertical_page_margin">@dimen/margin_medium</dimen> |
||||
|
||||
</resources> |
@ -1,374 +0,0 @@
@@ -1,374 +0,0 @@
|
||||
package org.purplei2p.i2pd; |
||||
|
||||
import java.io.BufferedReader; |
||||
import java.io.File; |
||||
import java.io.FileOutputStream; |
||||
import java.io.FileReader; |
||||
import java.io.FileWriter; |
||||
import java.io.IOException; |
||||
import java.io.InputStream; |
||||
import java.io.OutputStream; |
||||
import java.util.HashSet; |
||||
import java.util.Set; |
||||
|
||||
import android.annotation.TargetApi; |
||||
import android.content.res.AssetManager; |
||||
import android.net.ConnectivityManager; |
||||
import android.net.Network; |
||||
import android.net.NetworkCapabilities; |
||||
import android.net.NetworkRequest; |
||||
import android.os.Build; |
||||
import android.os.Environment; |
||||
import android.util.Log; |
||||
|
||||
import androidx.annotation.RequiresApi; |
||||
|
||||
public class DaemonWrapper { |
||||
private static final String TAG = "i2pd"; |
||||
private final AssetManager assetManager; |
||||
private final ConnectivityManager connectivityManager; |
||||
private String i2pdpath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/i2pd/"; |
||||
private boolean assetsCopied; |
||||
|
||||
public interface StateUpdateListener { |
||||
void daemonStateUpdate(State oldValue, State newValue); |
||||
} |
||||
|
||||
private final Set<StateUpdateListener> stateUpdateListeners = new HashSet<>(); |
||||
|
||||
public synchronized void addStateChangeListener(StateUpdateListener listener) { |
||||
stateUpdateListeners.add(listener); |
||||
} |
||||
|
||||
public synchronized void removeStateChangeListener(StateUpdateListener listener) { |
||||
stateUpdateListeners.remove(listener); |
||||
} |
||||
|
||||
private synchronized void setState(State newState) { |
||||
if (newState == null) |
||||
throw new NullPointerException(); |
||||
|
||||
State oldState = state; |
||||
|
||||
if (oldState == null) |
||||
throw new NullPointerException(); |
||||
|
||||
if (oldState.equals(newState)) |
||||
return; |
||||
|
||||
state = newState; |
||||
fireStateUpdate1(oldState, newState); |
||||
} |
||||
|
||||
public synchronized void stopAcceptingTunnels() { |
||||
if (isStartedOkay()) { |
||||
setState(State.gracefulShutdownInProgress); |
||||
I2PD_JNI.stopAcceptingTunnels(); |
||||
} |
||||
} |
||||
|
||||
public synchronized void startAcceptingTunnels() { |
||||
if (isStartedOkay()) { |
||||
setState(State.startedOkay); |
||||
I2PD_JNI.startAcceptingTunnels(); |
||||
} |
||||
} |
||||
|
||||
public synchronized void reloadTunnelsConfigs() { |
||||
if (isStartedOkay()) { |
||||
I2PD_JNI.reloadTunnelsConfigs(); |
||||
} |
||||
} |
||||
|
||||
public int getTransitTunnelsCount() { |
||||
return I2PD_JNI.GetTransitTunnelsCount(); |
||||
} |
||||
|
||||
public enum State { |
||||
uninitialized(R.string.uninitialized), |
||||
starting(R.string.starting), |
||||
jniLibraryLoaded(R.string.jniLibraryLoaded), |
||||
startedOkay(R.string.startedOkay), |
||||
startFailed(R.string.startFailed), |
||||
gracefulShutdownInProgress(R.string.gracefulShutdownInProgress), |
||||
stopped(R.string.stopped); |
||||
|
||||
State(int statusStringResourceId) { |
||||
this.statusStringResourceId = statusStringResourceId; |
||||
} |
||||
|
||||
private final int statusStringResourceId; |
||||
|
||||
public int getStatusStringResourceId() { |
||||
return statusStringResourceId; |
||||
} |
||||
|
||||
public boolean isStartedOkay() { |
||||
return equals(State.startedOkay) || equals(State.gracefulShutdownInProgress); |
||||
} |
||||
} |
||||
|
||||
private volatile State state = State.uninitialized; |
||||
|
||||
public State getState() { |
||||
return state; |
||||
} |
||||
|
||||
public DaemonWrapper(AssetManager assetManager, ConnectivityManager connectivityManager){ |
||||
this.assetManager = assetManager; |
||||
this.connectivityManager = connectivityManager; |
||||
setState(State.starting); |
||||
new Thread(() -> { |
||||
try { |
||||
processAssets(); |
||||
I2PD_JNI.loadLibraries(); |
||||
setState(State.jniLibraryLoaded); |
||||
registerNetworkCallback(); |
||||
} catch (Throwable tr) { |
||||
lastThrowable = tr; |
||||
setState(State.startFailed); |
||||
return; |
||||
} |
||||
try { |
||||
synchronized (DaemonWrapper.this) { |
||||
I2PD_JNI.setDataDir(Environment.getExternalStorageDirectory().getAbsolutePath() + "/i2pd"); |
||||
daemonStartResult = I2PD_JNI.startDaemon(); |
||||
if ("ok".equals(daemonStartResult)) { |
||||
setState(State.startedOkay); |
||||
} else |
||||
setState(State.startFailed); |
||||
} |
||||
} catch (Throwable tr) { |
||||
lastThrowable = tr; |
||||
setState(State.startFailed); |
||||
} |
||||
}, "i2pdDaemonStart").start(); |
||||
} |
||||
|
||||
private Throwable lastThrowable; |
||||
private String daemonStartResult = "N/A"; |
||||
|
||||
private void fireStateUpdate1(State oldValue, State newValue) { |
||||
Log.i(TAG, "daemon state change: " + state); |
||||
for (StateUpdateListener listener : stateUpdateListeners) { |
||||
try { |
||||
listener.daemonStateUpdate(oldValue, newValue); |
||||
} catch (Throwable tr) { |
||||
Log.e(TAG, "exception in listener ignored", tr); |
||||
} |
||||
} |
||||
} |
||||
|
||||
public Throwable getLastThrowable() { |
||||
return lastThrowable; |
||||
} |
||||
|
||||
public String getDaemonStartResult() { |
||||
return daemonStartResult; |
||||
} |
||||
|
||||
public boolean isStartedOkay() { |
||||
return getState().isStartedOkay(); |
||||
} |
||||
|
||||
public synchronized void stopDaemon() { |
||||
if (isStartedOkay()) { |
||||
try { |
||||
I2PD_JNI.stopDaemon(); |
||||
} catch(Throwable tr) { |
||||
Log.e(TAG, "", tr); |
||||
} |
||||
|
||||
setState(State.stopped); |
||||
} |
||||
} |
||||
|
||||
private void processAssets() { |
||||
if (!assetsCopied) { |
||||
try { |
||||
assetsCopied = true; |
||||
|
||||
File holderFile = new File(i2pdpath, "assets.ready"); |
||||
String versionName = BuildConfig.VERSION_NAME; // here will be app version, like 2.XX.XX
|
||||
StringBuilder text = new StringBuilder(); |
||||
|
||||
if (holderFile.exists()) { |
||||
try { // if holder file exists, read assets version string
|
||||
FileReader fileReader = new FileReader(holderFile); |
||||
|
||||
try { |
||||
BufferedReader br = new BufferedReader(fileReader); |
||||
|
||||
try { |
||||
String line; |
||||
|
||||
while ((line = br.readLine()) != null) { |
||||
text.append(line); |
||||
} |
||||
}finally { |
||||
try { |
||||
br.close(); |
||||
} catch (IOException e) { |
||||
Log.e(TAG, "", e); |
||||
} |
||||
} |
||||
} finally { |
||||
try { |
||||
fileReader.close(); |
||||
} catch (IOException e) { |
||||
Log.e(TAG, "", e); |
||||
} |
||||
} |
||||
} catch (IOException e) { |
||||
Log.e(TAG, "", e); |
||||
} |
||||
} |
||||
|
||||
// if version differs from current app version or null, try to delete certificates folder
|
||||
if (!text.toString().contains(versionName)) |
||||
try { |
||||
boolean deleteResult = holderFile.delete(); |
||||
if (!deleteResult) |
||||
Log.e(TAG, "holderFile.delete() returned " + deleteResult + ", absolute path='" + holderFile.getAbsolutePath() + "'"); |
||||
File certPath = new File(i2pdpath, "certificates"); |
||||
deleteRecursive(certPath); |
||||
} |
||||
catch (Throwable tr) { |
||||
Log.e(TAG, "", tr); |
||||
} |
||||
|
||||
// copy assets. If processed file exists, it won't be overwritten
|
||||
copyAsset("addressbook"); |
||||
copyAsset("certificates"); |
||||
copyAsset("tunnels.d"); |
||||
copyAsset("i2pd.conf"); |
||||
copyAsset("subscriptions.txt"); |
||||
copyAsset("tunnels.conf"); |
||||
|
||||
// update holder file about successful copying
|
||||
FileWriter writer = new FileWriter(holderFile); |
||||
try { |
||||
writer.append(versionName); |
||||
} finally { |
||||
try { |
||||
writer.close(); |
||||
} catch (IOException e) { |
||||
Log.e(TAG,"on writer close", e); |
||||
} |
||||
} |
||||
} |
||||
catch (Throwable tr) |
||||
{ |
||||
Log.e(TAG,"on assets copying", tr); |
||||
} |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Copy the asset at the specified path to this app's data directory. If the |
||||
* asset is a directory, its contents are also copied. |
||||
* |
||||
* @param path |
||||
* Path to asset, relative to app's assets directory. |
||||
*/ |
||||
private void copyAsset(String path) { |
||||
// If we have a directory, we make it and recurse. If a file, we copy its
|
||||
// contents.
|
||||
try { |
||||
String[] contents = assetManager.list(path); |
||||
|
||||
// The documentation suggests that list throws an IOException, but doesn't
|
||||
// say under what conditions. It'd be nice if it did so when the path was
|
||||
// to a file. That doesn't appear to be the case. If the returned array is
|
||||
// null or has 0 length, we assume the path is to a file. This means empty
|
||||
// directories will get turned into files.
|
||||
if (contents == null || contents.length == 0) { |
||||
copyFileAsset(path); |
||||
return; |
||||
} |
||||
|
||||
// Make the directory.
|
||||
File dir = new File(i2pdpath, path); |
||||
boolean result = dir.mkdirs(); |
||||
Log.d(TAG, "dir.mkdirs() returned " + result); |
||||
|
||||
// Recurse on the contents.
|
||||
for (String entry : contents) { |
||||
copyAsset(path + '/' + entry); |
||||
} |
||||
} catch (IOException e) { |
||||
Log.e(TAG, "ex ignored for path='" + path + "'", e); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Copy the asset file specified by path to app's data directory. Assumes |
||||
* parent directories have already been created. |
||||
* |
||||
* @param path |
||||
* Path to asset, relative to app's assets directory. |
||||
*/ |
||||
private void copyFileAsset(String path) { |
||||
File file = new File(i2pdpath, path); |
||||
if (!file.exists()) { |
||||
try { |
||||
try (InputStream in = assetManager.open(path)) { |
||||
try (OutputStream out = new FileOutputStream(file)) { |
||||
byte[] buffer = new byte[1024]; |
||||
int read = in.read(buffer); |
||||
while (read != -1) { |
||||
out.write(buffer, 0, read); |
||||
read = in.read(buffer); |
||||
} |
||||
} |
||||
} |
||||
} catch (IOException e) { |
||||
Log.e(TAG, "", e); |
||||
} |
||||
} |
||||
} |
||||
|
||||
private void deleteRecursive(File fileOrDirectory) { |
||||
if (fileOrDirectory.isDirectory()) { |
||||
File[] files = fileOrDirectory.listFiles(); |
||||
if (files != null) { |
||||
for (File child : files) { |
||||
deleteRecursive(child); |
||||
} |
||||
} |
||||
} |
||||
boolean deleteResult = fileOrDirectory.delete(); |
||||
if (!deleteResult) |
||||
Log.e(TAG, "fileOrDirectory.delete() returned " + deleteResult + ", absolute path='" + fileOrDirectory.getAbsolutePath() + "'"); |
||||
} |
||||
|
||||
private void registerNetworkCallback(){ |
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) registerNetworkCallback0(); |
||||
} |
||||
|
||||
@TargetApi(Build.VERSION_CODES.M) |
||||
private void registerNetworkCallback0() { |
||||
NetworkRequest request = new NetworkRequest.Builder() |
||||
.addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED) |
||||
.build(); |
||||
NetworkStateCallbackImpl networkCallback = new NetworkStateCallbackImpl(); |
||||
connectivityManager.registerNetworkCallback(request, networkCallback); |
||||
} |
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) |
||||
private static final class NetworkStateCallbackImpl extends ConnectivityManager.NetworkCallback { |
||||
@Override |
||||
public void onAvailable(Network network) { |
||||
super.onAvailable(network); |
||||
I2PD_JNI.onNetworkStateChanged(true); |
||||
Log.i(TAG, "NetworkCallback.onAvailable"); |
||||
} |
||||
|
||||
@Override |
||||
public void onLost(Network network) { |
||||
super.onLost(network); |
||||
I2PD_JNI.onNetworkStateChanged(false); |
||||
Log.i(TAG, " NetworkCallback.onLost"); |
||||
} |
||||
} |
||||
} |
@ -1,188 +0,0 @@
@@ -1,188 +0,0 @@
|
||||
package org.purplei2p.i2pd; |
||||
|
||||
import android.app.Notification; |
||||
import android.app.NotificationChannel; |
||||
import android.app.NotificationManager; |
||||
import android.app.PendingIntent; |
||||
import android.app.Service; |
||||
import android.content.Context; |
||||
import android.content.Intent; |
||||
import android.os.Binder; |
||||
import android.os.Build; |
||||
import android.os.IBinder; |
||||
import androidx.annotation.RequiresApi; |
||||
import androidx.core.app.NotificationCompat; |
||||
import android.util.Log; |
||||
|
||||
public class ForegroundService extends Service { |
||||
private static final String TAG="FgService"; |
||||
|
||||
private volatile boolean shown; |
||||
|
||||
private static ForegroundService instance; |
||||
|
||||
private static volatile DaemonWrapper daemon; |
||||
|
||||
private static final Object initDeinitLock = new Object(); |
||||
|
||||
private final DaemonWrapper.StateUpdateListener daemonStateUpdatedListener = |
||||
new DaemonWrapper.StateUpdateListener() { |
||||
|
||||
@Override |
||||
public void daemonStateUpdate(DaemonWrapper.State oldValue, DaemonWrapper.State newValue) { |
||||
updateNotificationText(); |
||||
} |
||||
}; |
||||
|
||||
private void updateNotificationText() { |
||||
try { |
||||
synchronized (initDeinitLock) { |
||||
if (shown) cancelNotification(); |
||||
showNotification(); |
||||
} |
||||
} catch (Throwable tr) { |
||||
Log.e(TAG,"error ignored",tr); |
||||
} |
||||
} |
||||
|
||||
|
||||
private NotificationManager notificationManager; |
||||
|
||||
// Unique Identification Number for the Notification.
|
||||
// We use it on Notification start, and to cancel it.
|
||||
private static final int NOTIFICATION = 1; |
||||
|
||||
/** |
||||
* Class for clients to access. Because we know this service always |
||||
* runs in the same process as its clients, we don't need to deal with |
||||
* IPC. |
||||
*/ |
||||
public class LocalBinder extends Binder { |
||||
ForegroundService getService() { |
||||
return ForegroundService.this; |
||||
} |
||||
} |
||||
|
||||
public static void init(DaemonWrapper daemon) { |
||||
ForegroundService.daemon = daemon; |
||||
initCheck(); |
||||
} |
||||
|
||||
private static void initCheck() { |
||||
synchronized (initDeinitLock) { |
||||
if (instance != null && daemon != null) instance.setListener(); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void onCreate() { |
||||
notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE); |
||||
instance = this; |
||||
initCheck(); |
||||
} |
||||
|
||||
private void setListener() { |
||||
daemon.addStateChangeListener(daemonStateUpdatedListener); |
||||
updateNotificationText(); |
||||
} |
||||
|
||||
@Override |
||||
public int onStartCommand(Intent intent, int flags, int startId) { |
||||
Log.i("ForegroundService", "Received start id " + startId + ": " + intent); |
||||
return START_STICKY; |
||||
} |
||||
|
||||
@Override |
||||
public void onDestroy() { |
||||
cancelNotification(); |
||||
deinitCheck(); |
||||
instance=null; |
||||
} |
||||
|
||||
public static void deinit() { |
||||
deinitCheck(); |
||||
} |
||||
|
||||
private static void deinitCheck() { |
||||
synchronized (initDeinitLock) { |
||||
if (daemon != null && instance != null) |
||||
daemon.removeStateChangeListener(instance.daemonStateUpdatedListener); |
||||
} |
||||
} |
||||
|
||||
private void cancelNotification() { |
||||
synchronized (initDeinitLock) { |
||||
// Cancel the persistent notification.
|
||||
notificationManager.cancel(NOTIFICATION); |
||||
|
||||
stopForeground(true); |
||||
|
||||
// Tell the user we stopped.
|
||||
//Toast.makeText(this, R.string.i2pd_service_stopped, Toast.LENGTH_SHORT).show();
|
||||
shown = false; |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public IBinder onBind(Intent intent) { |
||||
return mBinder; |
||||
} |
||||
|
||||
// This is the object that receives interactions from clients. See
|
||||
// RemoteService for a more complete example.
|
||||
private final IBinder mBinder = new LocalBinder(); |
||||
|
||||
/** |
||||
* Show a notification while this service is running. |
||||
*/ |
||||
private void showNotification() { |
||||
synchronized (initDeinitLock) { |
||||
if (daemon != null) { |
||||
// In this sample, we'll use the same text for the ticker and the expanded notification
|
||||
CharSequence text = getText(daemon.getState().getStatusStringResourceId()); |
||||
|
||||
// The PendingIntent to launch our activity if the user selects this notification
|
||||
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, |
||||
new Intent(this, I2PDActivity.class), 0); |
||||
|
||||
// If earlier version channel ID is not used
|
||||
// https://developer.android.com/reference/android/support/v4/app/NotificationCompat.Builder.html#NotificationCompat.Builder(android.content.Context)
|
||||
String channelId = Build.VERSION.SDK_INT >= 26 ? createNotificationChannel() : ""; |
||||
|
||||
// Set the info for the views that show in the notification panel.
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, channelId) |
||||
.setOngoing(true) |
||||
.setSmallIcon(R.drawable.itoopie_notification_icon); // the status icon
|
||||
if (Build.VERSION.SDK_INT >= 16) |
||||
builder = builder.setPriority(Notification.PRIORITY_DEFAULT); |
||||
if (Build.VERSION.SDK_INT >= 21) |
||||
builder = builder.setCategory(Notification.CATEGORY_SERVICE); |
||||
Notification notification = builder |
||||
.setTicker(text) // the status text
|
||||
.setWhen(System.currentTimeMillis()) // the time stamp
|
||||
.setContentTitle(getText(R.string.app_name)) // the label of the entry
|
||||
.setContentText(text) // the contents of the entry
|
||||
.setContentIntent(contentIntent) // The intent to send when the entry is clicked
|
||||
.build(); |
||||
|
||||
// Send the notification.
|
||||
//mNM.notify(NOTIFICATION, notification);
|
||||
startForeground(NOTIFICATION, notification); |
||||
shown = true; |
||||
} |
||||
} |
||||
} |
||||
|
||||
@RequiresApi(Build.VERSION_CODES.O) |
||||
private synchronized String createNotificationChannel() { |
||||
String channelId = getString(R.string.app_name); |
||||
CharSequence channelName = "I2Pd service"; |
||||
NotificationChannel chan = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_LOW); |
||||
//chan.setLightColor(Color.PURPLE);
|
||||
chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE); |
||||
NotificationManager service = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE); |
||||
if(service!=null)service.createNotificationChannel(chan); |
||||
else Log.e(TAG, "error: NOTIFICATION_SERVICE is null"); |
||||
return channelId; |
||||
} |
||||
} |
@ -1,486 +0,0 @@
@@ -1,486 +0,0 @@
|
||||
package org.purplei2p.i2pd; |
||||
|
||||
import java.io.PrintWriter; |
||||
import java.io.StringWriter; |
||||
import java.util.Timer; |
||||
import java.util.TimerTask; |
||||
|
||||
import android.Manifest; |
||||
import android.annotation.SuppressLint; |
||||
import android.app.Activity; |
||||
import android.app.AlertDialog; |
||||
import android.content.ActivityNotFoundException; |
||||
import android.content.ComponentName; |
||||
import android.content.Context; |
||||
import android.content.Intent; |
||||
import android.content.ServiceConnection; |
||||
import android.content.SharedPreferences; |
||||
import android.content.pm.PackageManager; |
||||
import android.net.ConnectivityManager; |
||||
import android.net.Uri; |
||||
import android.os.Bundle; |
||||
import android.os.Build; |
||||
import android.os.IBinder; |
||||
import android.os.PowerManager; |
||||
import android.preference.PreferenceManager; |
||||
import android.provider.Settings; |
||||
import android.util.Log; |
||||
import android.view.Menu; |
||||
import android.view.MenuItem; |
||||
import android.widget.TextView; |
||||
import android.widget.Toast; |
||||
|
||||
|
||||
import androidx.annotation.NonNull; |
||||
import androidx.core.app.ActivityCompat; |
||||
import androidx.core.content.ContextCompat; |
||||
|
||||
// For future package update checking
|
||||
|
||||
import android.webkit.WebSettings; |
||||
import android.webkit.WebView; |
||||
import android.webkit.WebViewClient; |
||||
|
||||
|
||||
import static android.provider.Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS; |
||||
|
||||
public class I2PDActivity extends Activity { |
||||
private static final String TAG = "i2pdActvt"; |
||||
private static final int MY_PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE = 1; |
||||
public static final int GRACEFUL_DELAY_MILLIS = 10 * 60 * 1000; |
||||
public static final String PACKAGE_URI_SCHEME = "package:"; |
||||
|
||||
private TextView textView; |
||||
//private ConfigParser parser = new ConfigParser(i2pdpath); // TODO
|
||||
|
||||
private static volatile DaemonWrapper daemon; |
||||
|
||||
private final DaemonWrapper.StateUpdateListener daemonStateUpdatedListener = new DaemonWrapper.StateUpdateListener() { |
||||
@Override |
||||
public void daemonStateUpdate(DaemonWrapper.State oldValue, DaemonWrapper.State newValue) { |
||||
updateStatusText(); |
||||
} |
||||
}; |
||||
|
||||
private void updateStatusText() { |
||||
runOnUiThread(() -> { |
||||
try { |
||||
if (textView == null) |
||||
return; |
||||
Throwable tr = daemon.getLastThrowable(); |
||||
if (tr!=null) { |
||||
textView.setText(throwableToString(tr)); |
||||
return; |
||||
} |
||||
DaemonWrapper.State state = daemon.getState(); |
||||
String startResultStr = DaemonWrapper.State.startFailed.equals(state) ? String.format(": %s", daemon.getDaemonStartResult()) : ""; |
||||
String graceStr = DaemonWrapper.State.gracefulShutdownInProgress.equals(state) ? String.format(": %s %s", formatGraceTimeRemaining(), getText(R.string.remaining)) : ""; |
||||
textView.setText(String.format("%s%s%s", getText(state.getStatusStringResourceId()), startResultStr, graceStr)); |
||||
} catch (Throwable tr) { |
||||
Log.e(TAG,"error ignored",tr); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
private static volatile long graceStartedMillis; |
||||
private static final Object graceStartedMillis_LOCK = new Object(); |
||||
private Menu optionsMenu; |
||||
|
||||
private static String formatGraceTimeRemaining() { |
||||
long remainingSeconds; |
||||
synchronized (graceStartedMillis_LOCK) { |
||||
remainingSeconds = Math.round(Math.max(0, graceStartedMillis + GRACEFUL_DELAY_MILLIS - System.currentTimeMillis()) / 1000.0D); |
||||
} |
||||
long remainingMinutes = (long)Math.floor(remainingSeconds / 60.0D); |
||||
long remSec = remainingSeconds - remainingMinutes * 60; |
||||
return remainingMinutes + ":" + (remSec / 10) + remSec % 10; |
||||
} |
||||
|
||||
@Override |
||||
public void onCreate(Bundle savedInstanceState) { |
||||
Log.i(TAG, "onCreate"); |
||||
super.onCreate(savedInstanceState); |
||||
|
||||
if (daemon==null) { |
||||
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); |
||||
daemon = new DaemonWrapper(getAssets(), connectivityManager); |
||||
} |
||||
ForegroundService.init(daemon); |
||||
|
||||
textView = new TextView(this); |
||||
setContentView(textView); |
||||
daemon.addStateChangeListener(daemonStateUpdatedListener); |
||||
daemonStateUpdatedListener.daemonStateUpdate(DaemonWrapper.State.uninitialized, daemon.getState()); |
||||
|
||||
// request permissions
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { |
||||
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { |
||||
ActivityCompat.requestPermissions(this, |
||||
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, |
||||
MY_PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE); |
||||
} |
||||
} |
||||
|
||||
// set the app be foreground
|
||||
doBindService(); |
||||
|
||||
final Timer gracefulQuitTimer = getGracefulQuitTimer(); |
||||
if (gracefulQuitTimer != null) { |
||||
long gracefulStopAtMillis; |
||||
synchronized (graceStartedMillis_LOCK) { |
||||
gracefulStopAtMillis = graceStartedMillis + GRACEFUL_DELAY_MILLIS; |
||||
} |
||||
rescheduleGraceStop(gracefulQuitTimer, gracefulStopAtMillis); |
||||
} |
||||
|
||||
openBatteryOptimizationDialogIfNeeded(); |
||||
|
||||
} |
||||
|
||||
@Override |
||||
protected void onDestroy() { |
||||
super.onDestroy(); |
||||
textView = null; |
||||
ForegroundService.deinit(); |
||||
daemon.removeStateChangeListener(daemonStateUpdatedListener); |
||||
//cancelGracefulStop0();
|
||||
try { |
||||
doUnbindService(); |
||||
} catch(Throwable tr) { |
||||
Log.e(TAG, "", tr); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) |
||||
{ |
||||
if (requestCode == MY_PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE) { |
||||
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) |
||||
Log.e(TAG, "WR_EXT_STORAGE perm granted"); |
||||
else { |
||||
Log.e(TAG, "WR_EXT_STORAGE perm declined, stopping i2pd"); |
||||
i2pdStop(); |
||||
//TODO must work w/o this perm, ask orignal
|
||||
} |
||||
} |
||||
} |
||||
|
||||
private void cancelGracefulStop0() { |
||||
Timer gracefulQuitTimer = getGracefulQuitTimer(); |
||||
if (gracefulQuitTimer != null) { |
||||
gracefulQuitTimer.cancel(); |
||||
setGracefulQuitTimer(null); |
||||
} |
||||
} |
||||
|
||||
private CharSequence throwableToString(Throwable tr) { |
||||
StringWriter sw = new StringWriter(8192); |
||||
PrintWriter pw = new PrintWriter(sw); |
||||
tr.printStackTrace(pw); |
||||
pw.close(); |
||||
return sw.toString(); |
||||
} |
||||
|
||||
// private LocalService mBoundService;
|
||||
|
||||
private ServiceConnection mConnection = new ServiceConnection() { |
||||
public void onServiceConnected(ComponentName className, IBinder service) { |
||||
// This is called when the connection with the service has been
|
||||
// established, giving us the service object we can use to
|
||||
// interact with the service. Because we have bound to a explicit
|
||||
// service that we know is running in our own process, we can
|
||||
// cast its IBinder to a concrete class and directly access it.
|
||||
// mBoundService = ((LocalService.LocalBinder)service).getService();
|
||||
|
||||
// Tell the user about this for our demo.
|
||||
// Toast.makeText(Binding.this, R.string.local_service_connected,
|
||||
// Toast.LENGTH_SHORT).show();
|
||||
} |
||||
|
||||
public void onServiceDisconnected(ComponentName className) { |
||||
// This is called when the connection with the service has been
|
||||
// unexpectedly disconnected -- that is, its process crashed.
|
||||
// Because it is running in our same process, we should never
|
||||
// see this happen.
|
||||
// mBoundService = null;
|
||||
// Toast.makeText(Binding.this, R.string.local_service_disconnected,
|
||||
// Toast.LENGTH_SHORT).show();
|
||||
} |
||||
}; |
||||
|
||||
private static volatile boolean mIsBound; |
||||
|
||||
private void doBindService() { |
||||
synchronized (I2PDActivity.class) { |
||||
if (mIsBound) |
||||
return; |
||||
// Establish a connection with the service. We use an explicit
|
||||
// class name because we want a specific service implementation that
|
||||
// we know will be running in our own process (and thus won't be
|
||||
// supporting component replacement by other applications).
|
||||
bindService(new Intent(this, ForegroundService.class), mConnection, Context.BIND_AUTO_CREATE); |
||||
mIsBound = true; |
||||
} |
||||
} |
||||
|
||||
private void doUnbindService() { |
||||
synchronized (I2PDActivity.class) { |
||||
if (mIsBound) { |
||||
// Detach our existing connection.
|
||||
unbindService(mConnection); |
||||
mIsBound = false; |
||||
} |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public boolean onCreateOptionsMenu(Menu menu) { |
||||
// Inflate the menu; this adds items to the action bar if it is present.
|
||||
getMenuInflater().inflate(R.menu.options_main, menu); |
||||
menu.findItem(R.id.action_battery_otimizations).setVisible(isBatteryOptimizationsOpenOsDialogApiAvailable()); |
||||
this.optionsMenu = menu; |
||||
return true; |
||||
} |
||||
|
||||
private boolean isBatteryOptimizationsOpenOsDialogApiAvailable() { |
||||
return android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M; |
||||
} |
||||
|
||||
@Override |
||||
public boolean onOptionsItemSelected(@NonNull MenuItem item) { |
||||
// Handle action bar item clicks here. The action bar will
|
||||
// automatically handle clicks on the Home/Up button, so long
|
||||
// as you specify a parent activity in AndroidManifest.xml.
|
||||
int id = item.getItemId(); |
||||
|
||||
switch(id) { |
||||
case R.id.action_stop: |
||||
i2pdStop(); |
||||
return true; |
||||
|
||||
case R.id.action_graceful_stop: |
||||
synchronized (graceStartedMillis_LOCK) { |
||||
if (getGracefulQuitTimer() != null) |
||||
cancelGracefulStop(); |
||||
else |
||||
i2pdGracefulStop(); |
||||
} |
||||
return true; |
||||
|
||||
case R.id.action_battery_otimizations: |
||||
onActionBatteryOptimizations(); |
||||
return true; |
||||
|
||||
case R.id.action_reload_tunnels_config: |
||||
onReloadTunnelsConfig(); |
||||
return true; |
||||
|
||||
case R.id.action_start_webview: |
||||
startActivity(new Intent(getApplicationContext(), WebConsoleActivity.class)); |
||||
return true; |
||||
} |
||||
|
||||
return super.onOptionsItemSelected(item); |
||||
} |
||||
|
||||
private void onActionBatteryOptimizations() { |
||||
if (isBatteryOptimizationsOpenOsDialogApiAvailable()) { |
||||
try { |
||||
startActivity(new Intent(ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS)); |
||||
} catch (ActivityNotFoundException e) { |
||||
Log.e(TAG, "BATT_OPTIM_DIALOG_ActvtNotFound", e); |
||||
Toast.makeText(this, R.string.os_version_does_not_support_battery_optimizations_show_os_dialog_api, Toast.LENGTH_SHORT).show(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
private void onReloadTunnelsConfig() { |
||||
Log.d(TAG, "reloading tunnels"); |
||||
daemon.reloadTunnelsConfigs(); |
||||
Toast.makeText(this, R.string.tunnels_reloading, Toast.LENGTH_SHORT).show(); |
||||
} |
||||
|
||||
private void i2pdStop() { |
||||
cancelGracefulStop0(); |
||||
new Thread(() -> { |
||||
Log.d(TAG, "stopping"); |
||||
try { |
||||
daemon.stopDaemon(); |
||||
} catch (Throwable tr) { |
||||
Log.e(TAG, "", tr); |
||||
} |
||||
quit(); //TODO make menu items for starting i2pd. On my Android, I need to reboot the OS to restart i2pd.
|
||||
}, "stop").start(); |
||||
} |
||||
|
||||
private static volatile Timer gracefulQuitTimer; |
||||
|
||||
private void i2pdGracefulStop() { |
||||
if (daemon.getState() == DaemonWrapper.State.stopped) { |
||||
Toast.makeText(this, R.string.already_stopped, Toast.LENGTH_SHORT).show(); |
||||
return; |
||||
} |
||||
if (getGracefulQuitTimer() != null) { |
||||
Toast.makeText(this, R.string.graceful_stop_is_already_in_progress, Toast.LENGTH_SHORT).show(); |
||||
return; |
||||
} |
||||
Toast.makeText(this, R.string.graceful_stop_is_in_progress, Toast.LENGTH_SHORT).show(); |
||||
new Thread(() -> { |
||||
try { |
||||
Log.d(TAG, "graceful stopping"); |
||||
if (daemon.isStartedOkay()) { |
||||
daemon.stopAcceptingTunnels(); |
||||
long gracefulStopAtMillis; |
||||
synchronized (graceStartedMillis_LOCK) { |
||||
graceStartedMillis = System.currentTimeMillis(); |
||||
gracefulStopAtMillis = graceStartedMillis + GRACEFUL_DELAY_MILLIS; |
||||
} |
||||
rescheduleGraceStop(null, gracefulStopAtMillis); |
||||
} else |
||||
i2pdStop(); |
||||
} catch(Throwable tr) { |
||||
Log.e(TAG, "", tr); |
||||
} |
||||
}, "gracInit").start(); |
||||
} |
||||
|
||||
private void cancelGracefulStop() |
||||
{ |
||||
cancelGracefulStop0(); |
||||
new Thread(() -> { |
||||
try { |
||||
Log.d(TAG, "canceling graceful stop"); |
||||
if (daemon.isStartedOkay()) { |
||||
daemon.startAcceptingTunnels(); |
||||
runOnUiThread(() -> Toast.makeText(this, R.string.shutdown_canceled, Toast.LENGTH_SHORT).show()); |
||||
} else |
||||
i2pdStop(); |
||||
} catch(Throwable tr) { |
||||
Log.e(TAG, "", tr); |
||||
} |
||||
}, "gracCancel").start(); |
||||
} |
||||
|
||||
private void rescheduleGraceStop(Timer gracefulQuitTimerOld, long gracefulStopAtMillis) { |
||||
if (gracefulQuitTimerOld != null) |
||||
gracefulQuitTimerOld.cancel(); |
||||
|
||||
if(daemon.getTransitTunnelsCount() <= 0) { // no tunnels left
|
||||
Log.d(TAG, "no transit tunnels left, stopping"); |
||||
i2pdStop(); |
||||
return; |
||||
} |
||||
|
||||
final Timer gracefulQuitTimer = new Timer(true); |
||||
setGracefulQuitTimer(gracefulQuitTimer); |
||||
gracefulQuitTimer.schedule(new TimerTask() { |
||||
|
||||
@Override |
||||
public void run() { |
||||
i2pdStop(); |
||||
} |
||||
|
||||
}, Math.max(0, gracefulStopAtMillis - System.currentTimeMillis())); |
||||
final TimerTask tickerTask = new TimerTask() { |
||||
@Override |
||||
public void run() { |
||||
updateStatusText(); |
||||
} |
||||
}; |
||||
gracefulQuitTimer.scheduleAtFixedRate(tickerTask, 0/*start delay*/, 1000/*millis period*/); |
||||
} |
||||
|
||||
private static Timer getGracefulQuitTimer() { |
||||
return gracefulQuitTimer; |
||||
} |
||||
|
||||
private void setGracefulQuitTimer(Timer gracefulQuitTimer) { |
||||
I2PDActivity.gracefulQuitTimer = gracefulQuitTimer; |
||||
runOnUiThread(()-> { |
||||
Menu menu = optionsMenu; |
||||
if (menu != null) { |
||||
MenuItem item = menu.findItem(R.id.action_graceful_stop); |
||||
if (item != null) { |
||||
synchronized (graceStartedMillis_LOCK) { |
||||
item.setTitle(getGracefulQuitTimer() != null ? R.string.action_cancel_graceful_stop : R.string.action_graceful_stop); |
||||
} |
||||
} |
||||
} |
||||
}); |
||||
} |
||||
|
||||
@SuppressLint("BatteryLife") |
||||
private void openBatteryOptimizationDialogIfNeeded() { |
||||
boolean questionEnabled = getPreferences().getBoolean(getBatteryOptimizationPreferenceKey(), true); |
||||
Log.i(TAG, "BATT_OPTIM_questionEnabled==" + questionEnabled); |
||||
if (!isKnownIgnoringBatteryOptimizations() |
||||
&& android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M |
||||
&& questionEnabled) { |
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this); |
||||
builder.setTitle(R.string.battery_optimizations_enabled); |
||||
builder.setMessage(R.string.battery_optimizations_enabled_dialog); |
||||
builder.setPositiveButton(R.string.continue_str, (dialog, which) -> { |
||||
try { |
||||
startActivity(new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS, Uri.parse(PACKAGE_URI_SCHEME + getPackageName()))); |
||||
} catch (ActivityNotFoundException e) { |
||||
Log.e(TAG, "BATT_OPTIM_ActvtNotFound", e); |
||||
Toast.makeText(this, R.string.device_does_not_support_disabling_battery_optimizations, Toast.LENGTH_SHORT).show(); |
||||
} |
||||
}); |
||||
builder.setOnDismissListener(dialog -> setNeverAskForBatteryOptimizationsAgain()); |
||||
final AlertDialog dialog = builder.create(); |
||||
dialog.setCanceledOnTouchOutside(false); |
||||
dialog.show(); |
||||
} |
||||
} |
||||
|
||||
private void setNeverAskForBatteryOptimizationsAgain() { |
||||
getPreferences().edit().putBoolean(getBatteryOptimizationPreferenceKey(), false).apply(); |
||||
} |
||||
|
||||
protected boolean isKnownIgnoringBatteryOptimizations() { |
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { |
||||
final PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE); |
||||
if (pm == null) { |
||||
Log.i(TAG, "BATT_OPTIM: POWER_SERVICE==null"); |
||||
return false; |
||||
} |
||||
boolean ignoring = pm.isIgnoringBatteryOptimizations(getPackageName()); |
||||
Log.i(TAG, "BATT_OPTIM: ignoring==" + ignoring); |
||||
return ignoring; |
||||
} else { |
||||
Log.i(TAG, "BATT_OPTIM: old sdk version==" + Build.VERSION.SDK_INT); |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
protected SharedPreferences getPreferences() { |
||||
return PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); |
||||
} |
||||
|
||||
private String getBatteryOptimizationPreferenceKey() { |
||||
@SuppressLint("HardwareIds") String device = Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID); |
||||
return "show_battery_optimization" + (device == null ? "" : device); |
||||
} |
||||
|
||||
private void quit() { |
||||
try { |
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { |
||||
finishAndRemoveTask(); |
||||
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { |
||||
finishAffinity(); |
||||
} else { |
||||
//moveTaskToBack(true);
|
||||
finish(); |
||||
} |
||||
} catch (Throwable tr) { |
||||
Log.e(TAG, "", tr); |
||||
} |
||||
try { |
||||
daemon.stopDaemon(); |
||||
} catch (Throwable tr) { |
||||
Log.e(TAG, "", tr); |
||||
} |
||||
System.exit(0); |
||||
} |
||||
} |
@ -1,170 +0,0 @@
@@ -1,170 +0,0 @@
|
||||
package org.purplei2p.i2pd; |
||||
|
||||
import android.Manifest; |
||||
import android.app.Activity; |
||||
import android.content.Intent; |
||||
import android.content.pm.PackageManager; |
||||
import android.os.Bundle; |
||||
import android.view.View; |
||||
import android.widget.Button; |
||||
import android.widget.TextView; |
||||
|
||||
import java.lang.reflect.Method; |
||||
|
||||
//dangerous perms, per https://developer.android.com/guide/topics/permissions/normal-permissions.html :
|
||||
//android.permission.WRITE_EXTERNAL_STORAGE
|
||||
public class I2PDPermsAskerActivity extends Activity { |
||||
|
||||
private static final int PERMISSION_WRITE_EXTERNAL_STORAGE = 0; |
||||
|
||||
private Button button_request_write_ext_storage_perms; |
||||
private TextView textview_retry; |
||||
|
||||
@Override |
||||
protected void onCreate(Bundle savedInstanceState) { |
||||
super.onCreate(savedInstanceState); |
||||
//if less than Android 6, no runtime perms req system present
|
||||
if (android.os.Build.VERSION.SDK_INT < 23) { |
||||
startMainActivity(); |
||||
return; |
||||
} |
||||
|
||||
|
||||
setContentView(R.layout.activity_perms_asker); |
||||
button_request_write_ext_storage_perms = (Button) findViewById(R.id.button_request_write_ext_storage_perms); |
||||
textview_retry = (TextView) findViewById(R.id.textview_retry); |
||||
|
||||
button_request_write_ext_storage_perms.setOnClickListener(new View.OnClickListener() { |
||||
@Override |
||||
public void onClick(View view) { |
||||
request_write_ext_storage_perms(); |
||||
} |
||||
}); |
||||
request_write_ext_storage_perms(); |
||||
} |
||||
|
||||
private void request_write_ext_storage_perms() { |
||||
|
||||
textview_retry.setVisibility(TextView.GONE); |
||||
button_request_write_ext_storage_perms.setVisibility(Button.GONE); |
||||
|
||||
Method methodCheckPermission; |
||||
Method method_shouldShowRequestPermissionRationale; |
||||
Method method_requestPermissions; |
||||
try { |
||||
methodCheckPermission = getClass().getMethod("checkSelfPermission", String.class); |
||||
method_shouldShowRequestPermissionRationale = |
||||
getClass().getMethod("shouldShowRequestPermissionRationale", String.class); |
||||
method_requestPermissions = |
||||
getClass().getMethod("requestPermissions", String[].class, int.class); |
||||
} catch (NoSuchMethodException e) { |
||||
throw new RuntimeException(e); |
||||
} |
||||
Integer resultObj; |
||||
try { |
||||
resultObj = (Integer) methodCheckPermission.invoke( |
||||
this, Manifest.permission.WRITE_EXTERNAL_STORAGE); |
||||
} catch (Throwable e) { |
||||
throw new RuntimeException(e); |
||||
} |
||||
|
||||
if (resultObj != PackageManager.PERMISSION_GRANTED) { |
||||
|
||||
// Should we show an explanation?
|
||||
Boolean aBoolean; |
||||
try { |
||||
aBoolean = (Boolean) method_shouldShowRequestPermissionRationale.invoke(this, |
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE); |
||||
} catch (Exception e) { |
||||
throw new RuntimeException(e); |
||||
} |
||||
if (aBoolean) { |
||||
|
||||
// Show an explanation to the user *asynchronously* -- don't block
|
||||
// this thread waiting for the user's response! After the user
|
||||
// sees the explanation, try again to request the permission.
|
||||
|
||||
showExplanation(); |
||||
|
||||
} else { |
||||
|
||||
// No explanation needed, we can request the permission.
|
||||
|
||||
try { |
||||
method_requestPermissions.invoke(this, |
||||
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, |
||||
PERMISSION_WRITE_EXTERNAL_STORAGE); |
||||
} catch (Exception e) { |
||||
throw new RuntimeException(e); |
||||
} |
||||
} |
||||
} else startMainActivity(); |
||||
} |
||||
|
||||
@Override |
||||
public void onRequestPermissionsResult(int requestCode, |
||||
String permissions[], int[] grantResults) { |
||||
switch (requestCode) { |
||||
case PERMISSION_WRITE_EXTERNAL_STORAGE: { |
||||
// If request is cancelled, the result arrays are empty.
|
||||
if (grantResults.length > 0 |
||||
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) { |
||||
|
||||
// permission was granted, yay! Do the
|
||||
// contacts-related task you need to do.
|
||||
|
||||
startMainActivity(); |
||||
|
||||
} else { |
||||
|
||||
// permission denied, boo! Disable the
|
||||
// functionality that depends on this permission.
|
||||
textview_retry.setText(R.string.permDenied); |
||||
textview_retry.setVisibility(TextView.VISIBLE); |
||||
button_request_write_ext_storage_perms.setVisibility(Button.VISIBLE); |
||||
} |
||||
} |
||||
|
||||
// other 'case' lines to check for other
|
||||
// permissions this app might request.
|
||||
} |
||||
} |
||||
|
||||
private void startMainActivity() { |
||||
startActivity(new Intent(this, I2PDActivity.class)); |
||||
finish(); |
||||
} |
||||
|
||||
private static final int SHOW_EXPLANATION_REQUEST = 1; // The request code
|
||||
private void showExplanation() { |
||||
Intent intent = new Intent(this, I2PDPermsExplanationActivity.class); |
||||
startActivityForResult(intent, SHOW_EXPLANATION_REQUEST); |
||||
} |
||||
|
||||
@Override |
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) { |
||||
// Check which request we're responding to
|
||||
if (requestCode == SHOW_EXPLANATION_REQUEST) { |
||||
// Make sure the request was successful
|
||||
if (resultCode == RESULT_OK) { |
||||
// Request the permission
|
||||
Method method_requestPermissions; |
||||
try { |
||||
method_requestPermissions = |
||||
getClass().getMethod("requestPermissions", String[].class, int.class); |
||||
} catch (NoSuchMethodException e) { |
||||
throw new RuntimeException(e); |
||||
} |
||||
try { |
||||
method_requestPermissions.invoke(this, |
||||
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, |
||||
PERMISSION_WRITE_EXTERNAL_STORAGE); |
||||
} catch (Exception e) { |
||||
throw new RuntimeException(e); |
||||
} |
||||
} else { |
||||
finish(); //close the app
|
||||
} |
||||
} |
||||
} |
||||
} |
@ -1,38 +0,0 @@
@@ -1,38 +0,0 @@
|
||||
package org.purplei2p.i2pd; |
||||
|
||||
import android.app.ActionBar; |
||||
import android.content.Intent; |
||||
import android.os.Bundle; |
||||
import android.app.Activity; |
||||
import android.view.View; |
||||
import android.widget.Button; |
||||
|
||||
public class I2PDPermsExplanationActivity extends Activity { |
||||
|
||||
@Override |
||||
protected void onCreate(Bundle savedInstanceState) { |
||||
super.onCreate(savedInstanceState); |
||||
setContentView(R.layout.activity_perms_explanation); |
||||
ActionBar actionBar = getActionBar(); |
||||
if(actionBar!=null)actionBar.setHomeButtonEnabled(false); |
||||
Button button_ok = (Button) findViewById(R.id.button_ok); |
||||
button_ok.setOnClickListener(new View.OnClickListener() { |
||||
@Override |
||||
public void onClick(View view) { |
||||
returnFromActivity(); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
private void returnFromActivity() { |
||||
Intent data = new Intent(); |
||||
Activity parent = getParent(); |
||||
if (parent == null) { |
||||
setResult(Activity.RESULT_OK, data); |
||||
} else { |
||||
parent.setResult(Activity.RESULT_OK, data); |
||||
} |
||||
finish(); |
||||
} |
||||
|
||||
} |
@ -1,31 +0,0 @@
@@ -1,31 +0,0 @@
|
||||
package org.purplei2p.i2pd; |
||||
|
||||
public class I2PD_JNI { |
||||
public static native String getABICompiledWith(); |
||||
|
||||
/** |
||||
* returns error info if failed |
||||
* returns "ok" if daemon initialized and started okay |
||||
*/ |
||||
public static native String startDaemon(); |
||||
|
||||
//should only be called after startDaemon() success
|
||||
public static native void stopDaemon(); |
||||
|
||||
public static native void stopAcceptingTunnels(); |
||||
|
||||
public static native void startAcceptingTunnels(); |
||||
|
||||
public static native void reloadTunnelsConfigs(); |
||||
|
||||
public static native void onNetworkStateChanged(boolean isConnected); |
||||
|
||||
public static native void setDataDir(String jdataDir); |
||||
|
||||
public static native int GetTransitTunnelsCount(); |
||||
|
||||
public static void loadLibraries() { |
||||
//System.loadLibrary("c++_shared");
|
||||
System.loadLibrary("i2pd"); |
||||
} |
||||
} |
@ -1,30 +0,0 @@
@@ -1,30 +0,0 @@
|
||||
package org.purplei2p.i2pd; |
||||
|
||||
import android.util.Log; |
||||
import android.content.BroadcastReceiver; |
||||
import android.content.Context; |
||||
import android.content.Intent; |
||||
import android.net.ConnectivityManager; |
||||
import android.net.NetworkInfo; |
||||
|
||||
public class NetworkStateChangeReceiver extends BroadcastReceiver { |
||||
|
||||
private static final String TAG = "i2pd"; |
||||
|
||||
//api level 1
|
||||
@Override |
||||
public void onReceive(final Context context, final Intent intent) { |
||||
Log.d(TAG,"Network state change"); |
||||
try { |
||||
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); |
||||
NetworkInfo activeNetworkInfo = cm.getActiveNetworkInfo(); |
||||
boolean isConnected = activeNetworkInfo!=null && activeNetworkInfo.isConnected(); |
||||
// https://developer.android.com/training/monitoring-device-state/connectivity-monitoring.html?hl=ru
|
||||
// boolean isWiFi = activeNetworkInfo!=null && (activeNetworkInfo.getType() == ConnectivityManager.TYPE_WIFI);
|
||||
|
||||
I2PD_JNI.onNetworkStateChanged(isConnected); |
||||
} catch (Throwable tr) { |
||||
Log.d(TAG,"",tr); |
||||
} |
||||
} |
||||
} |
@ -1,67 +0,0 @@
@@ -1,67 +0,0 @@
|
||||
package org.purplei2p.i2pd; |
||||
|
||||
import android.app.Activity; |
||||
import android.os.Bundle; |
||||
import android.os.Handler; |
||||
import android.view.MenuItem; |
||||
import android.webkit.WebSettings; |
||||
import android.webkit.WebView; |
||||
import android.webkit.WebViewClient; |
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; |
||||
|
||||
import java.util.Objects; |
||||
|
||||
public class WebConsoleActivity extends Activity { |
||||
private WebView webView; |
||||
private SwipeRefreshLayout swipeRefreshLayout; |
||||
|
||||
@Override |
||||
protected void onCreate(Bundle savedInstanceState) { |
||||
super.onCreate(savedInstanceState); |
||||
setContentView(R.layout.activity_web_console); |
||||
|
||||
Objects.requireNonNull(getActionBar()).setDisplayHomeAsUpEnabled(true); |
||||
|
||||
webView = (WebView) findViewById(R.id.webview1); |
||||
webView.setWebViewClient(new WebViewClient()); |
||||
|
||||
final WebSettings webSettings = webView.getSettings(); |
||||
webSettings.setBuiltInZoomControls(true); |
||||
webSettings.setJavaScriptEnabled(false); |
||||
webView.loadUrl("http://127.0.0.1:7070"); // TODO: instead 7070 I2Pd....HttpPort
|
||||
|
||||
swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipe); |
||||
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { |
||||
@Override |
||||
public void onRefresh() { |
||||
swipeRefreshLayout.setRefreshing(true); |
||||
new Handler().postDelayed(new Runnable() { |
||||
@Override |
||||
public void run() { |
||||
swipeRefreshLayout.setRefreshing(false); |
||||
webView.reload(); |
||||
} |
||||
}, 1000); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
@Override |
||||
public void onBackPressed() { |
||||
if (webView.canGoBack()) { |
||||
webView.goBack(); |
||||
} else { |
||||
super.onBackPressed(); |
||||
} |
||||
} |
||||
|
||||
public boolean onOptionsItemSelected(MenuItem item) { |
||||
int id = item.getItemId(); |
||||
|
||||
if (id == android.R.id.home) { |
||||
finish(); |
||||
return true; |
||||
} |
||||
return false; |
||||
} |
||||
} |
@ -1,13 +0,0 @@
@@ -1,13 +0,0 @@
|
||||
i2pd_qt.pro.user* |
||||
moc_* |
||||
ui_* |
||||
qrc_* |
||||
i2pd_qt |
||||
Makefile* |
||||
*.stash |
||||
object_script.* |
||||
i2pd_qt_plugin_import.cpp |
||||
i2pd_qt.pro.autosave* |
||||
build* |
||||
nohup.out |
||||
|
@ -1,21 +0,0 @@
@@ -1,21 +0,0 @@
|
||||
#include "AboutDialog.h" |
||||
#include "ui_AboutDialog.h" |
||||
#include <QDebug> |
||||
#include "version.h" |
||||
#include "BuildDateTimeQt.h" |
||||
|
||||
AboutDialog::AboutDialog(QWidget *parent) : |
||||
QDialog(parent), |
||||
ui(new Ui::AboutDialog) |
||||
{ |
||||
ui->setupUi(this); |
||||
ui->i2pdVersionLabel->setText(I2PD_VERSION); |
||||
ui->i2pVersionLabel->setText(I2P_VERSION); |
||||
ui->buildDateTimeLabel->setText(BUILD_DATE_TIME_QT); |
||||
ui->vcsCommitInfoLabel->setText(VCS_COMMIT_INFO); |
||||
} |
||||
|
||||
AboutDialog::~AboutDialog() |
||||
{ |
||||
delete ui; |
||||
} |
@ -1,22 +0,0 @@
@@ -1,22 +0,0 @@
|
||||
#ifndef ABOUTDIALOG_H |
||||
#define ABOUTDIALOG_H |
||||
|
||||
#include <QDialog> |
||||
|
||||
namespace Ui { |
||||
class AboutDialog; |
||||
} |
||||
|
||||
class AboutDialog : public QDialog |
||||
{ |
||||
Q_OBJECT |
||||
|
||||
public: |
||||
explicit AboutDialog(QWidget *parent = 0); |
||||
~AboutDialog(); |
||||
|
||||
private: |
||||
Ui::AboutDialog *ui; |
||||
}; |
||||
|
||||
#endif // ABOUTDIALOG_H
|
@ -1,194 +0,0 @@
@@ -1,194 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<ui version="4.0"> |
||||
<class>AboutDialog</class> |
||||
<widget class="QDialog" name="AboutDialog"> |
||||
<property name="windowModality"> |
||||
<enum>Qt::WindowModal</enum> |
||||
</property> |
||||
<property name="geometry"> |
||||
<rect> |
||||
<x>0</x> |
||||
<y>0</y> |
||||
<width>400</width> |
||||
<height>199</height> |
||||
</rect> |
||||
</property> |
||||
<property name="windowTitle"> |
||||
<string>About i2pd_qt</string> |
||||
</property> |
||||
<property name="windowIcon"> |
||||
<iconset resource="i2pd.qrc"> |
||||
<normaloff>:/icons/mask</normaloff>:/icons/mask</iconset> |
||||
</property> |
||||
<widget class="QDialogButtonBox" name="buttonBox"> |
||||
<property name="geometry"> |
||||
<rect> |
||||
<x>10</x> |
||||
<y>160</y> |
||||
<width>381</width> |
||||
<height>32</height> |
||||
</rect> |
||||
</property> |
||||
<property name="orientation"> |
||||
<enum>Qt::Horizontal</enum> |
||||
</property> |
||||
<property name="standardButtons"> |
||||
<set>QDialogButtonBox::Ok</set> |
||||
</property> |
||||
</widget> |
||||
<widget class="QLabel" name="label"> |
||||
<property name="geometry"> |
||||
<rect> |
||||
<x>10</x> |
||||
<y>10</y> |
||||
<width>381</width> |
||||
<height>17</height> |
||||
</rect> |
||||
</property> |
||||
<property name="text"> |
||||
<string><html><head/><body><p><span style=" font-weight:600;">About i2pd_qt</span></p></body></html></string> |
||||
</property> |
||||
</widget> |
||||
<widget class="QLabel" name="label_2"> |
||||
<property name="geometry"> |
||||
<rect> |
||||
<x>10</x> |
||||
<y>40</y> |
||||
<width>131</width> |
||||
<height>17</height> |
||||
</rect> |
||||
</property> |
||||
<property name="text"> |
||||
<string>i2pd Version:</string> |
||||
</property> |
||||
</widget> |
||||
<widget class="QLabel" name="label_3"> |
||||
<property name="geometry"> |
||||
<rect> |
||||
<x>10</x> |
||||
<y>70</y> |
||||
<width>131</width> |
||||
<height>17</height> |
||||
</rect> |
||||
</property> |
||||
<property name="text"> |
||||
<string>Build Date/Time:</string> |
||||
</property> |
||||
</widget> |
||||
<widget class="QLabel" name="i2pdVersionLabel"> |
||||
<property name="geometry"> |
||||
<rect> |
||||
<x>150</x> |
||||
<y>40</y> |
||||
<width>241</width> |
||||
<height>20</height> |
||||
</rect> |
||||
</property> |
||||
<property name="text"> |
||||
<string>I2PD_VERSION_LABEL</string> |
||||
</property> |
||||
</widget> |
||||
<widget class="QLabel" name="label_4"> |
||||
<property name="geometry"> |
||||
<rect> |
||||
<x>10</x> |
||||
<y>130</y> |
||||
<width>131</width> |
||||
<height>17</height> |
||||
</rect> |
||||
</property> |
||||
<property name="text"> |
||||
<string>I2P Version:</string> |
||||
</property> |
||||
</widget> |
||||
<widget class="QLabel" name="i2pVersionLabel"> |
||||
<property name="geometry"> |
||||
<rect> |
||||
<x>150</x> |
||||
<y>130</y> |
||||
<width>241</width> |
||||
<height>17</height> |
||||
</rect> |
||||
</property> |
||||
<property name="text"> |
||||
<string>I2P_VERSION_LABEL</string> |
||||
</property> |
||||
</widget> |
||||
<widget class="QLabel" name="buildDateTimeLabel"> |
||||
<property name="geometry"> |
||||
<rect> |
||||
<x>150</x> |
||||
<y>70</y> |
||||
<width>241</width> |
||||
<height>20</height> |
||||
</rect> |
||||
</property> |
||||
<property name="text"> |
||||
<string>BUILD_DATE_TIME_LABEL</string> |
||||
</property> |
||||
</widget> |
||||
<widget class="QLabel" name="label_5"> |
||||
<property name="geometry"> |
||||
<rect> |
||||
<x>10</x> |
||||
<y>100</y> |
||||
<width>131</width> |
||||
<height>17</height> |
||||
</rect> |
||||
</property> |
||||
<property name="text"> |
||||
<string>Version Control:</string> |
||||
</property> |
||||
</widget> |
||||
<widget class="QLabel" name="vcsCommitInfoLabel"> |
||||
<property name="geometry"> |
||||
<rect> |
||||
<x>150</x> |
||||
<y>100</y> |
||||
<width>241</width> |
||||
<height>17</height> |
||||
</rect> |
||||
</property> |
||||
<property name="text"> |
||||
<string>VCS_COMMIT_INFO_LABEL</string> |
||||
</property> |
||||
</widget> |
||||
</widget> |
||||
<resources> |
||||
<include location="i2pd.qrc"/> |
||||
</resources> |
||||
<connections> |
||||
<connection> |
||||
<sender>buttonBox</sender> |
||||
<signal>accepted()</signal> |
||||
<receiver>AboutDialog</receiver> |
||||
<slot>accept()</slot> |
||||
<hints> |
||||
<hint type="sourcelabel"> |
||||
<x>248</x> |
||||
<y>254</y> |
||||
</hint> |
||||
<hint type="destinationlabel"> |
||||
<x>157</x> |
||||
<y>274</y> |
||||
</hint> |
||||
</hints> |
||||
</connection> |
||||
<connection> |
||||
<sender>buttonBox</sender> |
||||
<signal>rejected()</signal> |
||||
<receiver>AboutDialog</receiver> |
||||
<slot>reject()</slot> |
||||
<hints> |
||||
<hint type="sourcelabel"> |
||||
<x>316</x> |
||||
<y>260</y> |
||||
</hint> |
||||
<hint type="destinationlabel"> |
||||
<x>286</x> |
||||
<y>274</y> |
||||
</hint> |
||||
</hints> |
||||
</connection> |
||||
</connections> |
||||
</ui> |
@ -1,7 +0,0 @@
@@ -1,7 +0,0 @@
|
||||
#ifndef BUILDDATETIMEQT_H |
||||
#define BUILDDATETIMEQT_H |
||||
|
||||
#include <QString> |
||||
const QString BUILD_DATE_TIME_QT = QStringLiteral(__DATE__ " " __TIME__); |
||||
|
||||
#endif // BUILDDATETIMEQT_H
|
@ -1,220 +0,0 @@
@@ -1,220 +0,0 @@
|
||||
#include "ClientTunnelPane.h" |
||||
#include "ClientContext.h" |
||||
#include "SignatureTypeComboboxFactory.h" |
||||
#include "QVBoxLayout" |
||||
|
||||
ClientTunnelPane::ClientTunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener, ClientTunnelConfig* tunconf, QWidget* wrongInputPane_, QLabel* wrongInputLabel_, MainWindow* mainWindow): |
||||
TunnelPane(tunnelsPageUpdateListener, tunconf, wrongInputPane_, wrongInputLabel_, mainWindow) {} |
||||
|
||||
void ClientTunnelPane::setGroupBoxTitle(const QString & title) { |
||||
clientTunnelNameGroupBox->setTitle(title); |
||||
} |
||||
|
||||
void ClientTunnelPane::deleteClientTunnelForm() { |
||||
TunnelPane::deleteTunnelForm(); |
||||
delete clientTunnelNameGroupBox; |
||||
clientTunnelNameGroupBox=nullptr; |
||||
|
||||
//gridLayoutWidget_2->deleteLater();
|
||||
//gridLayoutWidget_2=nullptr;
|
||||
} |
||||
|
||||
int ClientTunnelPane::appendClientTunnelForm( |
||||
ClientTunnelConfig* tunnelConfig, QWidget *tunnelsFormGridLayoutWidget, int tunnelsRow, int height) { |
||||
|
||||
ClientTunnelPane& ui = *this; |
||||
|
||||
clientTunnelNameGroupBox = new QGroupBox(tunnelsFormGridLayoutWidget); |
||||
clientTunnelNameGroupBox->setObjectName(QStringLiteral("clientTunnelNameGroupBox")); |
||||
|
||||
//tunnel
|
||||
gridLayoutWidget_2 = new QWidget(clientTunnelNameGroupBox); |
||||
|
||||
QComboBox *tunnelTypeComboBox = new QComboBox(gridLayoutWidget_2); |
||||
tunnelTypeComboBox->setObjectName(QStringLiteral("tunnelTypeComboBox")); |
||||
tunnelTypeComboBox->addItem("Client", i2p::client::I2P_TUNNELS_SECTION_TYPE_CLIENT); |
||||
tunnelTypeComboBox->addItem("Socks", i2p::client::I2P_TUNNELS_SECTION_TYPE_SOCKS); |
||||
tunnelTypeComboBox->addItem("Websocks", i2p::client::I2P_TUNNELS_SECTION_TYPE_WEBSOCKS); |
||||
tunnelTypeComboBox->addItem("HTTP Proxy", i2p::client::I2P_TUNNELS_SECTION_TYPE_HTTPPROXY); |
||||
tunnelTypeComboBox->addItem("UDP Client", i2p::client::I2P_TUNNELS_SECTION_TYPE_UDPCLIENT); |
||||
|
||||
int h=(7+4)*60; |
||||
gridLayoutWidget_2->setGeometry(QRect(0, 0, 561, h)); |
||||
clientTunnelNameGroupBox->setGeometry(QRect(0, 0, 561, h)); |
||||
|
||||
{ |
||||
const QString& type = tunnelConfig->getType(); |
||||
int index=0; |
||||
if(type==i2p::client::I2P_TUNNELS_SECTION_TYPE_CLIENT)tunnelTypeComboBox->setCurrentIndex(index); |
||||
++index; |
||||
if(type==i2p::client::I2P_TUNNELS_SECTION_TYPE_SOCKS)tunnelTypeComboBox->setCurrentIndex(index); |
||||
++index; |
||||
if(type==i2p::client::I2P_TUNNELS_SECTION_TYPE_WEBSOCKS)tunnelTypeComboBox->setCurrentIndex(index); |
||||
++index; |
||||
if(type==i2p::client::I2P_TUNNELS_SECTION_TYPE_HTTPPROXY)tunnelTypeComboBox->setCurrentIndex(index); |
||||
++index; |
||||
if(type==i2p::client::I2P_TUNNELS_SECTION_TYPE_UDPCLIENT)tunnelTypeComboBox->setCurrentIndex(index); |
||||
++index; |
||||
} |
||||
|
||||
setupTunnelPane(tunnelConfig, |
||||
clientTunnelNameGroupBox, |
||||
gridLayoutWidget_2, tunnelTypeComboBox, |
||||
tunnelsFormGridLayoutWidget, tunnelsRow, height, h); |
||||
//this->tunnelGroupBox->setGeometry(QRect(0, tunnelsFormGridLayoutWidget->height()+10, 561, (7+5)*40+10));
|
||||
|
||||
/*
|
||||
std::string destination; |
||||
*/ |
||||
|
||||
//host
|
||||
ui.horizontalLayout_2 = new QHBoxLayout(); |
||||
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); |
||||
ui.destinationLabel = new QLabel(gridLayoutWidget_2); |
||||
destinationLabel->setObjectName(QStringLiteral("destinationLabel")); |
||||
horizontalLayout_2->addWidget(destinationLabel); |
||||
ui.destinationLineEdit = new QLineEdit(gridLayoutWidget_2); |
||||
destinationLineEdit->setObjectName(QStringLiteral("destinationLineEdit")); |
||||
destinationLineEdit->setText(tunnelConfig->getdest().c_str()); |
||||
QObject::connect(destinationLineEdit, SIGNAL(textChanged(const QString &)), |
||||
this, SLOT(updated())); |
||||
horizontalLayout_2->addWidget(destinationLineEdit); |
||||
ui.destinationHorizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); |
||||
horizontalLayout_2->addItem(destinationHorizontalSpacer); |
||||
tunnelGridLayout->addLayout(horizontalLayout_2); |
||||
|
||||
/*
|
||||
* int port; |
||||
*/ |
||||
int gridIndex = 2; |
||||
{ |
||||
int port = tunnelConfig->getport(); |
||||
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); |
||||
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); |
||||
ui.portLabel = new QLabel(gridLayoutWidget_2); |
||||
portLabel->setObjectName(QStringLiteral("portLabel")); |
||||
horizontalLayout_2->addWidget(portLabel); |
||||
ui.portLineEdit = new QLineEdit(gridLayoutWidget_2); |
||||
portLineEdit->setObjectName(QStringLiteral("portLineEdit")); |
||||
portLineEdit->setText(QString::number(port)); |
||||
portLineEdit->setMaximumWidth(80); |
||||
QObject::connect(portLineEdit, SIGNAL(textChanged(const QString &)), |
||||
this, SLOT(updated())); |
||||
horizontalLayout_2->addWidget(portLineEdit); |
||||
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); |
||||
horizontalLayout_2->addItem(horizontalSpacer); |
||||
tunnelGridLayout->addLayout(horizontalLayout_2); |
||||
} |
||||
/*
|
||||
* std::string keys; |
||||
*/ |
||||
{ |
||||
std::string keys = tunnelConfig->getkeys(); |
||||
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); |
||||
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); |
||||
ui.keysLabel = new QLabel(gridLayoutWidget_2); |
||||
keysLabel->setObjectName(QStringLiteral("keysLabel")); |
||||
horizontalLayout_2->addWidget(keysLabel); |
||||
ui.keysLineEdit = new QLineEdit(gridLayoutWidget_2); |
||||
keysLineEdit->setObjectName(QStringLiteral("keysLineEdit")); |
||||
keysLineEdit->setText(keys.c_str()); |
||||
QObject::connect(keysLineEdit, SIGNAL(textChanged(const QString &)), |
||||
this, SLOT(updated())); |
||||
horizontalLayout_2->addWidget(keysLineEdit); |
||||
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); |
||||
horizontalLayout_2->addItem(horizontalSpacer); |
||||
tunnelGridLayout->addLayout(horizontalLayout_2); |
||||
} |
||||
/*
|
||||
* std::string address; |
||||
*/ |
||||
{ |
||||
std::string address = tunnelConfig->getaddress(); |
||||
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); |
||||
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); |
||||
ui.addressLabel = new QLabel(gridLayoutWidget_2); |
||||
addressLabel->setObjectName(QStringLiteral("addressLabel")); |
||||
horizontalLayout_2->addWidget(addressLabel); |
||||
ui.addressLineEdit = new QLineEdit(gridLayoutWidget_2); |
||||
addressLineEdit->setObjectName(QStringLiteral("addressLineEdit")); |
||||
addressLineEdit->setText(address.c_str()); |
||||
QObject::connect(addressLineEdit, SIGNAL(textChanged(const QString &)), |
||||
this, SLOT(updated())); |
||||
horizontalLayout_2->addWidget(addressLineEdit); |
||||
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); |
||||
horizontalLayout_2->addItem(horizontalSpacer); |
||||
tunnelGridLayout->addLayout(horizontalLayout_2); |
||||
} |
||||
|
||||
/*
|
||||
int destinationPort; |
||||
i2p::data::SigningKeyType sigType; |
||||
*/ |
||||
{ |
||||
int destinationPort = tunnelConfig->getdestinationPort(); |
||||
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); |
||||
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); |
||||
ui.destinationPortLabel = new QLabel(gridLayoutWidget_2); |
||||
destinationPortLabel->setObjectName(QStringLiteral("destinationPortLabel")); |
||||
horizontalLayout_2->addWidget(destinationPortLabel); |
||||
ui.destinationPortLineEdit = new QLineEdit(gridLayoutWidget_2); |
||||
destinationPortLineEdit->setObjectName(QStringLiteral("destinationPortLineEdit")); |
||||
destinationPortLineEdit->setText(QString::number(destinationPort)); |
||||
destinationPortLineEdit->setMaximumWidth(80); |
||||
QObject::connect(destinationPortLineEdit, SIGNAL(textChanged(const QString &)), |
||||
this, SLOT(updated())); |
||||
horizontalLayout_2->addWidget(destinationPortLineEdit); |
||||
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); |
||||
horizontalLayout_2->addItem(horizontalSpacer); |
||||
tunnelGridLayout->addLayout(horizontalLayout_2); |
||||
} |
||||
{ |
||||
int cryptoType = tunnelConfig->getcryptoType(); |
||||
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); |
||||
ui.cryptoTypeLabel = new QLabel(gridLayoutWidget_2); |
||||
cryptoTypeLabel->setObjectName(QStringLiteral("cryptoTypeLabel")); |
||||
horizontalLayout_2->addWidget(cryptoTypeLabel); |
||||
ui.cryptoTypeLineEdit = new QLineEdit(gridLayoutWidget_2); |
||||
cryptoTypeLineEdit->setObjectName(QStringLiteral("cryptoTypeLineEdit")); |
||||
cryptoTypeLineEdit->setText(QString::number(cryptoType)); |
||||
cryptoTypeLineEdit->setMaximumWidth(80); |
||||
QObject::connect(cryptoTypeLineEdit, SIGNAL(textChanged(const QString &)), |
||||
this, SLOT(updated())); |
||||
horizontalLayout_2->addWidget(cryptoTypeLineEdit); |
||||
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); |
||||
horizontalLayout_2->addItem(horizontalSpacer); |
||||
tunnelGridLayout->addLayout(horizontalLayout_2); |
||||
} |
||||
{ |
||||
i2p::data::SigningKeyType sigType = tunnelConfig->getsigType(); |
||||
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); |
||||
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); |
||||
ui.sigTypeLabel = new QLabel(gridLayoutWidget_2); |
||||
sigTypeLabel->setObjectName(QStringLiteral("sigTypeLabel")); |
||||
horizontalLayout_2->addWidget(sigTypeLabel); |
||||
ui.sigTypeComboBox = SignatureTypeComboBoxFactory::createSignatureTypeComboBox(gridLayoutWidget_2, sigType); |
||||
sigTypeComboBox->setObjectName(QStringLiteral("sigTypeComboBox")); |
||||
QObject::connect(sigTypeComboBox, SIGNAL(currentIndexChanged(int)), |
||||
this, SLOT(updated())); |
||||
horizontalLayout_2->addWidget(sigTypeComboBox); |
||||
QPushButton * lockButton2 = new QPushButton(gridLayoutWidget_2); |
||||
horizontalLayout_2->addWidget(lockButton2); |
||||
widgetlocks.add(new widgetlock(sigTypeComboBox, lockButton2)); |
||||
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); |
||||
horizontalLayout_2->addItem(horizontalSpacer); |
||||
tunnelGridLayout->addLayout(horizontalLayout_2); |
||||
} |
||||
{ |
||||
I2CPParameters& i2cpParameters = tunnelConfig->getI2cpParameters(); |
||||
appendControlsForI2CPParameters(i2cpParameters, gridIndex); |
||||
} |
||||
|
||||
retranslateClientTunnelForm(ui); |
||||
|
||||
tunnelGridLayout->invalidate(); |
||||
|
||||
return h; |
||||
} |
||||
|
||||
ServerTunnelPane* ClientTunnelPane::asServerTunnelPane(){return nullptr;} |
||||
ClientTunnelPane* ClientTunnelPane::asClientTunnelPane(){return this;} |
@ -1,126 +0,0 @@
@@ -1,126 +0,0 @@
|
||||
#ifndef CLIENTTUNNELPANE_H |
||||
#define CLIENTTUNNELPANE_H |
||||
|
||||
#include "QGridLayout" |
||||
#include "QVBoxLayout" |
||||
|
||||
#include "TunnelPane.h" |
||||
|
||||
class ClientTunnelConfig; |
||||
|
||||
class ServerTunnelPane; |
||||
class TunnelPane; |
||||
|
||||
class ClientTunnelPane : public TunnelPane { |
||||
Q_OBJECT |
||||
public: |
||||
ClientTunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener, ClientTunnelConfig* tunconf, QWidget* wrongInputPane_, QLabel* wrongInputLabel_, MainWindow* mainWindow); |
||||
virtual ~ClientTunnelPane(){} |
||||
virtual ServerTunnelPane* asServerTunnelPane(); |
||||
virtual ClientTunnelPane* asClientTunnelPane(); |
||||
int appendClientTunnelForm(ClientTunnelConfig* tunnelConfig, QWidget *tunnelsFormGridLayoutWidget, |
||||
int tunnelsRow, int height); |
||||
void deleteClientTunnelForm(); |
||||
private: |
||||
QGroupBox *clientTunnelNameGroupBox; |
||||
|
||||
//tunnel
|
||||
QWidget *gridLayoutWidget_2; |
||||
|
||||
//destination
|
||||
QHBoxLayout *horizontalLayout_2; |
||||
QLabel *destinationLabel; |
||||
QLineEdit *destinationLineEdit; |
||||
QSpacerItem *destinationHorizontalSpacer; |
||||
|
||||
//port
|
||||
QLabel * portLabel; |
||||
QLineEdit * portLineEdit; |
||||
|
||||
//keys
|
||||
QLabel * keysLabel; |
||||
QLineEdit * keysLineEdit; |
||||
|
||||
//address
|
||||
QLabel * addressLabel; |
||||
QLineEdit * addressLineEdit; |
||||
|
||||
//destinationPort
|
||||
QLabel * destinationPortLabel; |
||||
QLineEdit * destinationPortLineEdit; |
||||
|
||||
//sigType
|
||||
QLabel * sigTypeLabel; |
||||
QComboBox * sigTypeComboBox; |
||||
|
||||
//cryptoType
|
||||
QLabel * cryptoTypeLabel; |
||||
QLineEdit * cryptoTypeLineEdit; |
||||
|
||||
protected slots: |
||||
virtual void setGroupBoxTitle(const QString & title); |
||||
|
||||
private: |
||||
void retranslateClientTunnelForm(ClientTunnelPane& /*ui*/) { |
||||
typeLabel->setText(QApplication::translate("cltTunForm", "Client tunnel type:", 0)); |
||||
destinationLabel->setText(QApplication::translate("cltTunForm", "Destination:", 0)); |
||||
portLabel->setText(QApplication::translate("cltTunForm", "Port:", 0)); |
||||
cryptoTypeLabel->setText(QApplication::translate("cltTunForm", "Crypto type:", 0)); |
||||
keysLabel->setText(QApplication::translate("cltTunForm", "Keys:", 0)); |
||||
destinationPortLabel->setText(QApplication::translate("cltTunForm", "Destination port:", 0)); |
||||
addressLabel->setText(QApplication::translate("cltTunForm", "Address:", 0)); |
||||
sigTypeLabel->setText(QApplication::translate("cltTunForm", "Signature type:", 0)); |
||||
} |
||||
protected: |
||||
virtual bool applyDataFromUIToTunnelConfig() { |
||||
QString cannotSaveSettings = QApplication::tr("Cannot save settings."); |
||||
bool ok=TunnelPane::applyDataFromUIToTunnelConfig(); |
||||
if(!ok)return false; |
||||
ClientTunnelConfig* ctc=tunnelConfig->asClientTunnelConfig(); |
||||
assert(ctc!=nullptr); |
||||
|
||||
if(!isValidSingleLine(destinationLineEdit))return false; |
||||
if(!isValidSingleLine(portLineEdit))return false; |
||||
if(!isValidSingleLine(cryptoTypeLineEdit))return false; |
||||
if(!isValidSingleLine(keysLineEdit))return false; |
||||
if(!isValidSingleLine(addressLineEdit))return false; |
||||
if(!isValidSingleLine(destinationPortLineEdit))return false; |
||||
|
||||
//destination
|
||||
ctc->setdest(destinationLineEdit->text().toStdString()); |
||||
|
||||
auto portStr=portLineEdit->text(); |
||||
int portInt=portStr.toInt(&ok); |
||||
|
||||
if(!ok){ |
||||
highlightWrongInput(QApplication::tr("Bad port, must be int.")+" "+cannotSaveSettings,portLineEdit); |
||||
return false; |
||||
} |
||||
ctc->setport(portInt); |
||||
|
||||
auto cryptoTypeStr=cryptoTypeLineEdit->text(); |
||||
int cryptoTypeInt=cryptoTypeStr.toInt(&ok); |
||||
if(!ok){ |
||||
highlightWrongInput(QApplication::tr("Bad crypto type, must be int.")+" "+cannotSaveSettings,cryptoTypeLineEdit); |
||||
return false; |
||||
} |
||||
ctc->setcryptoType(cryptoTypeInt); |
||||
|
||||
ctc->setkeys(keysLineEdit->text().toStdString()); |
||||
|
||||
ctc->setaddress(addressLineEdit->text().toStdString()); |
||||
|
||||
auto dportStr=destinationPortLineEdit->text(); |
||||
int dportInt=dportStr.toInt(&ok); |
||||
if(!ok){ |
||||
highlightWrongInput(QApplication::tr("Bad destinationPort, must be int.")+" "+cannotSaveSettings,destinationPortLineEdit); |
||||
return false; |
||||
} |
||||
ctc->setdestinationPort(dportInt); |
||||
|
||||
ctc->setsigType(readSigTypeComboboxUI(sigTypeComboBox)); |
||||
return true; |
||||
} |
||||
}; |
||||
|
||||
#endif // CLIENTTUNNELPANE_H
|
@ -1,195 +0,0 @@
@@ -1,195 +0,0 @@
|
||||
#include <memory> |
||||
|
||||
#include "DaemonQT.h" |
||||
#include "Daemon.h" |
||||
#include "mainwindow.h" |
||||
|
||||
#include "Log.h" |
||||
|
||||
#include <QMessageBox> |
||||
#include <QApplication> |
||||
#include <QMutexLocker> |
||||
#include <QThread> |
||||
|
||||
//#define DEBUG_WITH_DEFAULT_LOGGING (1)
|
||||
|
||||
namespace i2p |
||||
{ |
||||
namespace qt |
||||
{ |
||||
Worker::Worker (DaemonQTImpl& daemon): |
||||
m_Daemon (daemon) |
||||
{ |
||||
} |
||||
|
||||
void Worker::startDaemon() |
||||
{ |
||||
qDebug("Performing daemon start..."); |
||||
//try{
|
||||
m_Daemon.start(); |
||||
qDebug("Daemon started."); |
||||
emit resultReady(false, ""); |
||||
/*}catch(std::exception ex){
|
||||
emit resultReady(true, ex.what()); |
||||
}catch(...){ |
||||
emit resultReady(true, QObject::tr("Error: unknown exception")); |
||||
}*/ |
||||
} |
||||
void Worker::restartDaemon() |
||||
{ |
||||
qDebug("Performing daemon restart..."); |
||||
//try{
|
||||
m_Daemon.restart(); |
||||
qDebug("Daemon restarted."); |
||||
emit resultReady(false, ""); |
||||
/*}catch(std::exception ex){
|
||||
emit resultReady(true, ex.what()); |
||||
}catch(...){ |
||||
emit resultReady(true, QObject::tr("Error: unknown exception")); |
||||
}*/ |
||||
} |
||||
void Worker::stopDaemon() { |
||||
qDebug("Performing daemon stop..."); |
||||
//try{
|
||||
m_Daemon.stop(); |
||||
qDebug("Daemon stopped."); |
||||
emit resultReady(false, ""); |
||||
/*}catch(std::exception ex){
|
||||
emit resultReady(true, ex.what()); |
||||
}catch(...){ |
||||
emit resultReady(true, QObject::tr("Error: unknown exception")); |
||||
}*/ |
||||
} |
||||
|
||||
Controller::Controller(DaemonQTImpl& daemon): |
||||
m_Daemon (daemon) |
||||
{ |
||||
Worker *worker = new Worker (m_Daemon); |
||||
worker->moveToThread(&workerThread); |
||||
connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater); |
||||
connect(this, &Controller::startDaemon, worker, &Worker::startDaemon); |
||||
connect(this, &Controller::stopDaemon, worker, &Worker::stopDaemon); |
||||
connect(this, &Controller::restartDaemon, worker, &Worker::restartDaemon); |
||||
connect(worker, &Worker::resultReady, this, &Controller::handleResults); |
||||
workerThread.start(); |
||||
} |
||||
Controller::~Controller() |
||||
{ |
||||
qDebug("Closing and waiting for daemon worker thread..."); |
||||
workerThread.quit(); |
||||
workerThread.wait(); |
||||
qDebug("Waiting for daemon worker thread finished."); |
||||
if(m_Daemon.isRunning()) |
||||
{ |
||||
qDebug("Stopping the daemon..."); |
||||
m_Daemon.stop(); |
||||
qDebug("Stopped the daemon."); |
||||
} |
||||
} |
||||
|
||||
DaemonQTImpl::DaemonQTImpl (): |
||||
mutex(nullptr), m_IsRunning(nullptr), m_RunningChangedCallback(nullptr) |
||||
{ |
||||
} |
||||
|
||||
DaemonQTImpl::~DaemonQTImpl () |
||||
{ |
||||
delete mutex; |
||||
} |
||||
|
||||
bool DaemonQTImpl::init(int argc, char* argv[], std::shared_ptr<std::ostream> logstream) |
||||
{ |
||||
mutex=new QMutex(QMutex::Recursive); |
||||
setRunningCallback(0); |
||||
m_IsRunning=false; |
||||
return Daemon.init(argc,argv,logstream); |
||||
} |
||||
|
||||
void DaemonQTImpl::start() |
||||
{ |
||||
QMutexLocker locker(mutex); |
||||
setRunning(true); |
||||
Daemon.start(); |
||||
} |
||||
|
||||
void DaemonQTImpl::stop() |
||||
{ |
||||
QMutexLocker locker(mutex); |
||||
Daemon.stop(); |
||||
setRunning(false); |
||||
} |
||||
|
||||
void DaemonQTImpl::restart() |
||||
{ |
||||
QMutexLocker locker(mutex); |
||||
stop(); |
||||
start(); |
||||
} |
||||
|
||||
void DaemonQTImpl::setRunningCallback(runningChangedCallback cb) |
||||
{ |
||||
m_RunningChangedCallback = cb; |
||||
} |
||||
|
||||
bool DaemonQTImpl::isRunning() |
||||
{ |
||||
return m_IsRunning; |
||||
} |
||||
|
||||
void DaemonQTImpl::setRunning(bool newValue) |
||||
{ |
||||
bool oldValue = m_IsRunning; |
||||
if(oldValue!=newValue) |
||||
{ |
||||
m_IsRunning = newValue; |
||||
if(m_RunningChangedCallback) |
||||
m_RunningChangedCallback(); |
||||
} |
||||
} |
||||
|
||||
int RunQT (int argc, char* argv[]) |
||||
{ |
||||
QApplication app(argc, argv); |
||||
int result; |
||||
|
||||
{ |
||||
std::shared_ptr<std::iostream> logstreamptr= |
||||
#ifdef DEBUG_WITH_DEFAULT_LOGGING |
||||
nullptr |
||||
#else |
||||
std::make_shared<std::stringstream>() |
||||
#endif |
||||
; |
||||
//TODO move daemon init deinit to a bg thread
|
||||
DaemonQTImpl daemon; |
||||
if(logstreamptr) (*logstreamptr) << "Initialising the daemon..." << std::endl; |
||||
bool daemonInitSuccess = daemon.init(argc, argv, logstreamptr); |
||||
if(!daemonInitSuccess) |
||||
{ |
||||
QMessageBox::critical(0, "Error", "Daemon init failed"); |
||||
return 1; |
||||
} |
||||
LogPrint(eLogDebug, "Initialised, creating the main window..."); |
||||
MainWindow w(logstreamptr); |
||||
LogPrint(eLogDebug, "Before main window.show()..."); |
||||
w.show (); |
||||
|
||||
{ |
||||
i2p::qt::Controller daemonQtController(daemon); |
||||
w.setI2PController(&daemonQtController); |
||||
LogPrint(eLogDebug, "Starting the daemon..."); |
||||
emit daemonQtController.startDaemon(); |
||||
//daemon.start ();
|
||||
LogPrint(eLogDebug, "Starting GUI event loop..."); |
||||
result = app.exec(); |
||||
//daemon.stop ();
|
||||
} |
||||
} |
||||
|
||||
//QMessageBox::information(&w, "Debug", "demon stopped");
|
||||
LogPrint(eLogDebug, "Exiting the application"); |
||||
return result; |
||||
} |
||||
} |
||||
} |
||||
|
@ -1,88 +0,0 @@
@@ -1,88 +0,0 @@
|
||||
#ifndef DAEMONQT_H |
||||
#define DAEMONQT_H |
||||
|
||||
#include <memory> |
||||
#include <QObject> |
||||
#include <QThread> |
||||
#include <QMutex> |
||||
#include <QMessageBox> |
||||
|
||||
namespace i2p |
||||
{ |
||||
namespace qt |
||||
{ |
||||
class DaemonQTImpl |
||||
{ |
||||
public: |
||||
|
||||
DaemonQTImpl (); |
||||
~DaemonQTImpl (); |
||||
|
||||
typedef void (*runningChangedCallback)(); |
||||
|
||||
/**
|
||||
* @brief init |
||||
* @param argc |
||||
* @param argv |
||||
* @return success |
||||
*/ |
||||
bool init(int argc, char* argv[], std::shared_ptr<std::ostream> logstream); |
||||
void start(); |
||||
void stop(); |
||||
void restart(); |
||||
void setRunningCallback(runningChangedCallback cb); |
||||
bool isRunning(); |
||||
private: |
||||
void setRunning(bool running); |
||||
void showError(std::string errorMsg); |
||||
private: |
||||
QMutex* mutex; |
||||
bool m_IsRunning; |
||||
runningChangedCallback m_RunningChangedCallback; |
||||
}; |
||||
|
||||
class Worker : public QObject |
||||
{ |
||||
Q_OBJECT |
||||
public: |
||||
|
||||
Worker (DaemonQTImpl& daemon); |
||||
|
||||
private: |
||||
|
||||
DaemonQTImpl& m_Daemon; |
||||
|
||||
public slots: |
||||
void startDaemon(); |
||||
void restartDaemon(); |
||||
void stopDaemon(); |
||||
|
||||
signals: |
||||
void resultReady(bool failed, QString failureMessage); |
||||
}; |
||||
|
||||
class Controller : public QObject |
||||
{ |
||||
Q_OBJECT |
||||
QThread workerThread; |
||||
public: |
||||
Controller(DaemonQTImpl& daemon); |
||||
~Controller(); |
||||
private: |
||||
DaemonQTImpl& m_Daemon; |
||||
|
||||
public slots: |
||||
void handleResults(bool failed, QString failureMessage){ |
||||
if(failed){ |
||||
QMessageBox::critical(0, QObject::tr("Error"), failureMessage); |
||||
} |
||||
} |
||||
signals: |
||||
void startDaemon(); |
||||
void stopDaemon(); |
||||
void restartDaemon(); |
||||
}; |
||||
} |
||||
} |
||||
|
||||
#endif // DAEMONQT_H
|
@ -1,3 +0,0 @@
@@ -1,3 +0,0 @@
|
||||
#include "DelayedSaveManager.h" |
||||
|
||||
DelayedSaveManager::DelayedSaveManager(){} |
@ -1,26 +0,0 @@
@@ -1,26 +0,0 @@
|
||||
#ifndef DELAYEDSAVEMANAGER_H |
||||
#define DELAYEDSAVEMANAGER_H |
||||
|
||||
#include "Saver.h" |
||||
#include "I2pdQtTypes.h" |
||||
|
||||
class DelayedSaveManager |
||||
{ |
||||
public: |
||||
DelayedSaveManager(); |
||||
|
||||
virtual void setSaver(Saver* saver)=0; |
||||
|
||||
typedef unsigned int DATA_SERIAL_TYPE; |
||||
|
||||
virtual void delayedSave(bool reloadAfterSave, DATA_SERIAL_TYPE dataSerial, FocusEnum focusOn, std::string tunnelNameToFocus, QWidget* widgetToFocus)=0; |
||||
|
||||
//returns false iff save failed
|
||||
virtual bool appExiting()=0; |
||||
|
||||
virtual FocusEnum getFocusOn()=0; |
||||
virtual std::string& getTunnelNameToFocus()=0; |
||||
virtual QWidget* getWidgetToFocus()=0; |
||||
}; |
||||
|
||||
#endif // DELAYEDSAVEMANAGER_H
|
@ -1,140 +0,0 @@
@@ -1,140 +0,0 @@
|
||||
#include "DelayedSaveManagerImpl.h" |
||||
|
||||
#include <assert.h> |
||||
|
||||
DelayedSaveManagerImpl::DelayedSaveManagerImpl() : |
||||
widgetToFocus(nullptr), |
||||
saver(nullptr), |
||||
lastDataSerialSeen(DelayedSaveManagerImpl::INITIAL_DATA_SERIAL), |
||||
lastSaveStartedTimestamp(A_VERY_OBSOLETE_TIMESTAMP), |
||||
exiting(false), |
||||
thread(new DelayedSaveThread(this)) |
||||
{ |
||||
} |
||||
|
||||
void DelayedSaveManagerImpl::setSaver(Saver* saver) { |
||||
this->saver = saver; |
||||
} |
||||
|
||||
void DelayedSaveManagerImpl::start() { |
||||
thread->start(); |
||||
} |
||||
|
||||
bool DelayedSaveManagerImpl::isSaverValid() { |
||||
return saver != nullptr; |
||||
} |
||||
|
||||
void DelayedSaveManagerImpl::delayedSave(bool reloadAfterSave, DATA_SERIAL_TYPE dataSerial, FocusEnum focusOn, std::string tunnelNameToFocus, QWidget* widgetToFocus) { |
||||
if(lastDataSerialSeen==dataSerial)return; |
||||
this->reloadAfterSave = reloadAfterSave; |
||||
this->focusOn = focusOn; |
||||
this->tunnelNameToFocus = tunnelNameToFocus; |
||||
this->widgetToFocus = widgetToFocus; |
||||
lastDataSerialSeen=dataSerial; |
||||
assert(isSaverValid()); |
||||
TIMESTAMP_TYPE now = getTime(); |
||||
TIMESTAMP_TYPE wakeTime = lastSaveStartedTimestamp + DelayedSaveThread::WAIT_TIME_MILLIS; |
||||
if(now < wakeTime) { |
||||
//defer save until lastSaveStartedTimestamp + DelayedSaveThread::WAIT_TIME_MILLIS
|
||||
thread->deferSaveUntil(wakeTime); |
||||
return; |
||||
} |
||||
lastSaveStartedTimestamp = now; |
||||
thread->startSavingNow(); |
||||
} |
||||
|
||||
bool DelayedSaveManagerImpl::appExiting() { |
||||
exiting=true; |
||||
thread->wakeThreadAndJoinThread(); |
||||
assert(isSaverValid()); |
||||
saver->save(false, FocusEnum::noFocus); |
||||
return true; |
||||
} |
||||
|
||||
DelayedSaveThread::DelayedSaveThread(DelayedSaveManagerImpl* delayedSaveManagerImpl_): |
||||
delayedSaveManagerImpl(delayedSaveManagerImpl_), |
||||
mutex(new QMutex()), |
||||
waitCondition(new QWaitCondition()), |
||||
saveNow(false), |
||||
defer(false) |
||||
{ |
||||
mutex->lock(); |
||||
} |
||||
|
||||
DelayedSaveThread::~DelayedSaveThread(){ |
||||
mutex->unlock(); |
||||
delete mutex; |
||||
delete waitCondition; |
||||
} |
||||
|
||||
void DelayedSaveThread::run() { |
||||
forever { |
||||
if(delayedSaveManagerImpl->isExiting())return; |
||||
waitCondition->wait(mutex, WAIT_TIME_MILLIS); |
||||
if(delayedSaveManagerImpl->isExiting())return; |
||||
Saver* saver = delayedSaveManagerImpl->getSaver(); |
||||
assert(saver!=nullptr); |
||||
if(saveNow) { |
||||
saveNow = false; |
||||
const FocusEnum focusOn = delayedSaveManagerImpl->getFocusOn(); |
||||
const std::string tunnelNameToFocus = delayedSaveManagerImpl->getTunnelNameToFocus(); |
||||
QWidget* widgetToFocus = delayedSaveManagerImpl->getWidgetToFocus(); |
||||
saver->save(delayedSaveManagerImpl->isReloadAfterSave(), focusOn, tunnelNameToFocus, widgetToFocus); |
||||
continue; |
||||
} |
||||
if(defer) { |
||||
defer=false; |
||||
#define max(a,b) (((a)>(b))?(a):(b)) |
||||
forever { |
||||
TIMESTAMP_TYPE now = DelayedSaveManagerImpl::getTime(); |
||||
TIMESTAMP_TYPE millisToWait = max(wakeTime-now, 0); |
||||
if(millisToWait>0) { |
||||
waitCondition->wait(mutex, millisToWait); |
||||
if(delayedSaveManagerImpl->isExiting())return; |
||||
continue; |
||||
} |
||||
const FocusEnum focusOn = delayedSaveManagerImpl->getFocusOn(); |
||||
const std::string tunnelNameToFocus = delayedSaveManagerImpl->getTunnelNameToFocus(); |
||||
QWidget* widgetToFocus = delayedSaveManagerImpl->getWidgetToFocus(); |
||||
saver->save(delayedSaveManagerImpl->isReloadAfterSave(), focusOn, tunnelNameToFocus, widgetToFocus); |
||||
break; //break inner loop
|
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
void DelayedSaveThread::wakeThreadAndJoinThread() { |
||||
waitCondition->wakeAll(); |
||||
quit(); |
||||
wait();//join //"similar to the POSIX pthread_join()"
|
||||
} |
||||
|
||||
DelayedSaveManagerImpl::TIMESTAMP_TYPE DelayedSaveManagerImpl::getTime() { |
||||
return QDateTime::currentMSecsSinceEpoch(); |
||||
} |
||||
|
||||
void DelayedSaveThread::deferSaveUntil(TIMESTAMP_TYPE wakeTime_) { |
||||
wakeTime = wakeTime_; |
||||
defer = true; |
||||
waitCondition->wakeAll(); |
||||
} |
||||
|
||||
void DelayedSaveThread::startSavingNow() { |
||||
//mutex->lock();
|
||||
saveNow=true; |
||||
waitCondition->wakeAll(); |
||||
//mutex->unlock();
|
||||
} |
||||
|
||||
DelayedSaveManagerImpl::~DelayedSaveManagerImpl() { |
||||
thread->wakeThreadAndJoinThread(); |
||||
delete thread; |
||||
} |
||||
|
||||
bool DelayedSaveManagerImpl::isExiting() { |
||||
return exiting; |
||||
} |
||||
Saver* DelayedSaveManagerImpl::getSaver() { |
||||
return saver; |
||||
} |
||||
|
@ -1,84 +0,0 @@
@@ -1,84 +0,0 @@
|
||||
#ifndef DELAYEDSAVEMANAGERIMPL_H |
||||
#define DELAYEDSAVEMANAGERIMPL_H |
||||
|
||||
#include <QObject> |
||||
#include <QThread> |
||||
#include <QWaitCondition> |
||||
#include <QMutex> |
||||
#include <QDateTime> |
||||
|
||||
#include "I2pdQtTypes.h" |
||||
#include "DelayedSaveManager.h" |
||||
#include "Saver.h" |
||||
|
||||
class DelayedSaveManagerImpl; |
||||
class Saver; |
||||
|
||||
class DelayedSaveThread : public QThread { |
||||
Q_OBJECT |
||||
|
||||
public: |
||||
static constexpr unsigned long WAIT_TIME_MILLIS = 1000L; |
||||
|
||||
typedef qint64 TIMESTAMP_TYPE; |
||||
static constexpr TIMESTAMP_TYPE A_VERY_OBSOLETE_TIMESTAMP=0; |
||||
|
||||
DelayedSaveThread(DelayedSaveManagerImpl* delayedSaveManagerImpl); |
||||
virtual ~DelayedSaveThread(); |
||||
|
||||
void run() override; |
||||
|
||||
void deferSaveUntil(TIMESTAMP_TYPE wakeTime); |
||||
void startSavingNow(); |
||||
|
||||
void wakeThreadAndJoinThread(); |
||||
|
||||
private: |
||||
DelayedSaveManagerImpl* delayedSaveManagerImpl; |
||||
QMutex* mutex; |
||||
QWaitCondition* waitCondition; |
||||
volatile bool saveNow; |
||||
volatile bool defer; |
||||
volatile TIMESTAMP_TYPE wakeTime; |
||||
}; |
||||
|
||||
class DelayedSaveManagerImpl : public DelayedSaveManager { |
||||
FocusEnum focusOn; |
||||
std::string tunnelNameToFocus; |
||||
QWidget* widgetToFocus; |
||||
bool reloadAfterSave; |
||||
public: |
||||
DelayedSaveManagerImpl(); |
||||
virtual ~DelayedSaveManagerImpl(); |
||||
virtual void setSaver(Saver* saver); |
||||
virtual void start(); |
||||
virtual void delayedSave(bool reloadAfterSave, DATA_SERIAL_TYPE dataSerial, FocusEnum focusOn, std::string tunnelNameToFocus, QWidget* widgetToFocus); |
||||
virtual bool appExiting(); |
||||
|
||||
typedef DelayedSaveThread::TIMESTAMP_TYPE TIMESTAMP_TYPE; |
||||
|
||||
static constexpr DATA_SERIAL_TYPE INITIAL_DATA_SERIAL=0; |
||||
bool isExiting(); |
||||
Saver* getSaver(); |
||||
static TIMESTAMP_TYPE getTime(); |
||||
|
||||
bool isReloadAfterSave() { return reloadAfterSave; } |
||||
FocusEnum getFocusOn() { return focusOn; } |
||||
std::string& getTunnelNameToFocus() { return tunnelNameToFocus; } |
||||
QWidget* getWidgetToFocus() { return widgetToFocus; } |
||||
|
||||
private: |
||||
Saver* saver; |
||||
bool isSaverValid(); |
||||
|
||||
DATA_SERIAL_TYPE lastDataSerialSeen; |
||||
|
||||
static constexpr TIMESTAMP_TYPE A_VERY_OBSOLETE_TIMESTAMP=DelayedSaveThread::A_VERY_OBSOLETE_TIMESTAMP; |
||||
TIMESTAMP_TYPE lastSaveStartedTimestamp; |
||||
|
||||
bool exiting; |
||||
DelayedSaveThread* thread; |
||||
void wakeThreadAndJoinThread(); |
||||
}; |
||||
|
||||
#endif // DELAYEDSAVEMANAGERIMPL_H
|
@ -1,7 +0,0 @@
@@ -1,7 +0,0 @@
|
||||
#ifndef I2PDQTTYPES_H |
||||
#define I2PDQTTYPES_H |
||||
|
||||
enum WrongInputPageEnum { generalSettingsPage, tunnelsSettingsPage }; |
||||
enum FocusEnum { noFocus, focusOnTunnelName, focusOnWidget }; |
||||
|
||||
#endif // I2PDQTTYPES_H
|
@ -1,12 +0,0 @@
@@ -1,12 +0,0 @@
|
||||
#include "I2pdQtUtil.h" |
||||
|
||||
bool isValidSingleLine(QLineEdit* widget, WrongInputPageEnum inputPage, MainWindow* mainWindow) { |
||||
bool correct = !widget->text().contains(QRegularExpression("[\r\n]"), nullptr); |
||||
if(!correct) { |
||||
mainWindow->highlightWrongInput( |
||||
QApplication::tr("Single line input expected, but it's multiline"), |
||||
inputPage, |
||||
widget); |
||||
} |
||||
return correct; |
||||
} |
@ -1,9 +0,0 @@
@@ -1,9 +0,0 @@
|
||||
#ifndef I2pdQtUtil_H |
||||
#define I2pdQtUtil_H |
||||
|
||||
class QLineEdit; |
||||
#include "mainwindow.h" |
||||
|
||||
bool isValidSingleLine(QLineEdit* widget, WrongInputPageEnum inputPage, MainWindow* mainWindow); |
||||
|
||||
#endif // I2pdQtUtil_H
|
@ -1,2 +0,0 @@
@@ -1,2 +0,0 @@
|
||||
#include "MainWindowItems.h" |
||||
|
@ -1,17 +0,0 @@
@@ -1,17 +0,0 @@
|
||||
#ifndef MAINWINDOWITEMS_H |
||||
#define MAINWINDOWITEMS_H |
||||
|
||||
#include <QString> |
||||
#include <QLineEdit> |
||||
#include <QPushButton> |
||||
#include <QComboBox> |
||||
#include <QCheckBox> |
||||
|
||||
#include <sstream> |
||||
#include <functional> |
||||
|
||||
#include "mainwindow.h" |
||||
|
||||
class MainWindow; |
||||
|
||||
#endif // MAINWINDOWITEMS_H
|
@ -1,3 +0,0 @@
@@ -1,3 +0,0 @@
|
||||
# Build Requirements |
||||
|
||||
* Qt 5 is necessary (because Qt4 lacks QtWidgets/ folder) |
@ -1,6 +0,0 @@
@@ -1,6 +0,0 @@
|
||||
#include "Saver.h" |
||||
|
||||
Saver::Saver() |
||||
{ |
||||
|
||||
} |
@ -1,25 +0,0 @@
@@ -1,25 +0,0 @@
|
||||
#ifndef SAVER_H |
||||
#define SAVER_H |
||||
|
||||
#include <string> |
||||
#include <QObject> |
||||
#include <QString> |
||||
class QWidget; |
||||
|
||||
#include "I2pdQtTypes.h" |
||||
|
||||
class Saver : public QObject |
||||
{ |
||||
Q_OBJECT |
||||
|
||||
public: |
||||
Saver(); |
||||
//FocusEnum::focusNone iff failures //??? wtf
|
||||
virtual bool save(bool reloadAfterSave, const FocusEnum focusOn, const std::string& tunnelNameToFocus="", QWidget* widgetToFocus=nullptr)=0; |
||||
|
||||
signals: |
||||
void reloadTunnelsConfigAndUISignal(const QString); |
||||
|
||||
}; |
||||
|
||||
#endif // SAVER_H
|
@ -1,81 +0,0 @@
@@ -1,81 +0,0 @@
|
||||
#include "SaverImpl.h" |
||||
|
||||
#include <fstream> |
||||
#include <assert.h> |
||||
#include <sstream> |
||||
|
||||
#include "QList" |
||||
#include "QString" |
||||
|
||||
#include "mainwindow.h" |
||||
|
||||
SaverImpl::SaverImpl(MainWindow *mainWindowPtr_, QList<MainWindowItem*> * configItems_, std::map<std::string,TunnelConfig*>* tunnelConfigs_) : |
||||
configItems(configItems_), tunnelConfigs(tunnelConfigs_), confpath(), tunconfpath(), mainWindowPtr(mainWindowPtr_) |
||||
{} |
||||
|
||||
SaverImpl::~SaverImpl() {} |
||||
|
||||
bool SaverImpl::save(bool reloadAfterSave, const FocusEnum focusOn, const std::string& tunnelNameToFocus, QWidget* widgetToFocus) { |
||||
//save main config
|
||||
{ |
||||
std::stringstream out; |
||||
for(QList<MainWindowItem*>::iterator it = configItems->begin(); it!= configItems->end(); ++it) { |
||||
MainWindowItem* item = *it; |
||||
item->saveToStringStream(out); |
||||
} |
||||
|
||||
using namespace std; |
||||
|
||||
|
||||
QString backup=confpath+"~"; |
||||
if(QFile::exists(backup)) QFile::remove(backup);//TODO handle errors
|
||||
if(QFile::exists(confpath)) QFile::rename(confpath, backup);//TODO handle errors
|
||||
ofstream outfile; |
||||
outfile.open(confpath.toStdString());//TODO handle errors
|
||||
outfile << out.str().c_str(); |
||||
outfile.close(); |
||||
} |
||||
|
||||
//save tunnels config
|
||||
{ |
||||
std::stringstream out; |
||||
|
||||
for (std::map<std::string,TunnelConfig*>::iterator it=tunnelConfigs->begin(); it!=tunnelConfigs->end(); ++it) { |
||||
//const std::string& name = it->first;
|
||||
TunnelConfig* tunconf = it->second; |
||||
tunconf->saveHeaderToStringStream(out); |
||||
tunconf->saveToStringStream(out); |
||||
tunconf->saveI2CPParametersToStringStream(out); |
||||
} |
||||
|
||||
using namespace std; |
||||
|
||||
QString backup=tunconfpath+"~"; |
||||
if(QFile::exists(backup)) QFile::remove(backup);//TODO handle errors
|
||||
if(QFile::exists(tunconfpath)) QFile::rename(tunconfpath, backup);//TODO handle errors
|
||||
ofstream outfile; |
||||
outfile.open(tunconfpath.toStdString());//TODO handle errors
|
||||
outfile << out.str().c_str(); |
||||
outfile.close(); |
||||
} |
||||
|
||||
if(reloadAfterSave) { |
||||
//reload saved configs
|
||||
#if 0 |
||||
i2p::client::context.ReloadConfig(); |
||||
#endif |
||||
|
||||
if(reloadAfterSave) emit reloadTunnelsConfigAndUISignal(focusOn==FocusEnum::focusOnTunnelName?QString::fromStdString(tunnelNameToFocus):""); |
||||
} |
||||
|
||||
return true; |
||||
} |
||||
|
||||
void SaverImpl::setConfPath(QString& confpath_) { confpath = confpath_; } |
||||
|
||||
void SaverImpl::setTunnelsConfPath(QString& tunconfpath_) { tunconfpath = tunconfpath_; } |
||||
|
||||
/*void SaverImpl::setTunnelFocus(bool focusOnTunnel, std::string tunnelNameToFocus) {
|
||||
this->focusOnTunnel=focusOnTunnel; |
||||
this->tunnelNameToFocus=tunnelNameToFocus; |
||||
}*/ |
@ -1,33 +0,0 @@
@@ -1,33 +0,0 @@
|
||||
#ifndef SAVERIMPL_H |
||||
#define SAVERIMPL_H |
||||
|
||||
#include <map> |
||||
#include <string> |
||||
|
||||
#include <QObject> |
||||
#include "QList" |
||||
|
||||
#include "mainwindow.h" |
||||
#include "TunnelConfig.h" |
||||
#include "Saver.h" |
||||
|
||||
class MainWindowItem; |
||||
class TunnelConfig; |
||||
|
||||
class SaverImpl : public Saver |
||||
{ |
||||
public: |
||||
SaverImpl(MainWindow *mainWindowPtr_, QList<MainWindowItem*> * configItems_, std::map<std::string,TunnelConfig*>* tunnelConfigs_); |
||||
virtual ~SaverImpl(); |
||||
virtual bool save(bool reloadAfterSave, const FocusEnum focusOn, const std::string& tunnelNameToFocus, QWidget* widgetToFocus); |
||||
void setConfPath(QString& confpath_); |
||||
void setTunnelsConfPath(QString& tunconfpath_); |
||||
private: |
||||
QList<MainWindowItem*> * configItems; |
||||
std::map<std::string,TunnelConfig*>* tunnelConfigs; |
||||
QString confpath; |
||||
QString tunconfpath; |
||||
MainWindow* mainWindowPtr; |
||||
}; |
||||
|
||||
#endif // SAVERIMPL_H
|
@ -1,278 +0,0 @@
@@ -1,278 +0,0 @@
|
||||
#include "ServerTunnelPane.h" |
||||
#include "ClientContext.h" |
||||
#include "SignatureTypeComboboxFactory.h" |
||||
|
||||
ServerTunnelPane::ServerTunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener, ServerTunnelConfig* tunconf, QWidget* wrongInputPane_, QLabel* wrongInputLabel_, MainWindow* mainWindow): |
||||
TunnelPane(tunnelsPageUpdateListener, tunconf, wrongInputPane_, wrongInputLabel_, mainWindow) {} |
||||
|
||||
void ServerTunnelPane::setGroupBoxTitle(const QString & title) { |
||||
serverTunnelNameGroupBox->setTitle(title); |
||||
} |
||||
|
||||
int ServerTunnelPane::appendServerTunnelForm( |
||||
ServerTunnelConfig* tunnelConfig, QWidget *tunnelsFormGridLayoutWidget, int tunnelsRow, int height) { |
||||
|
||||
ServerTunnelPane& ui = *this; |
||||
|
||||
serverTunnelNameGroupBox = new QGroupBox(tunnelsFormGridLayoutWidget); |
||||
serverTunnelNameGroupBox->setObjectName(QStringLiteral("serverTunnelNameGroupBox")); |
||||
|
||||
//tunnel
|
||||
gridLayoutWidget_2 = new QWidget(serverTunnelNameGroupBox); |
||||
|
||||
QComboBox *tunnelTypeComboBox = new QComboBox(gridLayoutWidget_2); |
||||
tunnelTypeComboBox->setObjectName(QStringLiteral("tunnelTypeComboBox")); |
||||
tunnelTypeComboBox->addItem("Server", i2p::client::I2P_TUNNELS_SECTION_TYPE_SERVER); |
||||
tunnelTypeComboBox->addItem("HTTP", i2p::client::I2P_TUNNELS_SECTION_TYPE_HTTP); |
||||
tunnelTypeComboBox->addItem("IRC", i2p::client::I2P_TUNNELS_SECTION_TYPE_IRC); |
||||
tunnelTypeComboBox->addItem("UDP Server", i2p::client::I2P_TUNNELS_SECTION_TYPE_UDPSERVER); |
||||
|
||||
int h=19*60; |
||||
gridLayoutWidget_2->setGeometry(QRect(0, 0, 561, h)); |
||||
serverTunnelNameGroupBox->setGeometry(QRect(0, 0, 561, h)); |
||||
|
||||
{ |
||||
const QString& type = tunnelConfig->getType(); |
||||
int index=0; |
||||
if(type==i2p::client::I2P_TUNNELS_SECTION_TYPE_SERVER)tunnelTypeComboBox->setCurrentIndex(index); |
||||
++index; |
||||
if(type==i2p::client::I2P_TUNNELS_SECTION_TYPE_HTTP)tunnelTypeComboBox->setCurrentIndex(index); |
||||
++index; |
||||
if(type==i2p::client::I2P_TUNNELS_SECTION_TYPE_IRC)tunnelTypeComboBox->setCurrentIndex(index); |
||||
++index; |
||||
if(type==i2p::client::I2P_TUNNELS_SECTION_TYPE_UDPSERVER)tunnelTypeComboBox->setCurrentIndex(index); |
||||
++index; |
||||
} |
||||
|
||||
setupTunnelPane(tunnelConfig, |
||||
serverTunnelNameGroupBox, |
||||
gridLayoutWidget_2, tunnelTypeComboBox, |
||||
tunnelsFormGridLayoutWidget, tunnelsRow, height, h); |
||||
//this->tunnelGroupBox->setGeometry(QRect(0, tunnelsFormGridLayoutWidget->height()+10, 561, 18*40+10));
|
||||
|
||||
//host
|
||||
ui.horizontalLayout_2 = new QHBoxLayout(); |
||||
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); |
||||
ui.hostLabel = new QLabel(gridLayoutWidget_2); |
||||
hostLabel->setObjectName(QStringLiteral("hostLabel")); |
||||
horizontalLayout_2->addWidget(hostLabel); |
||||
ui.hostLineEdit = new QLineEdit(gridLayoutWidget_2); |
||||
hostLineEdit->setObjectName(QStringLiteral("hostLineEdit")); |
||||
hostLineEdit->setText(tunnelConfig->gethost().c_str()); |
||||
QObject::connect(hostLineEdit, SIGNAL(textChanged(const QString &)), |
||||
this, SLOT(updated())); |
||||
horizontalLayout_2->addWidget(hostLineEdit); |
||||
ui.hostHorizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); |
||||
horizontalLayout_2->addItem(hostHorizontalSpacer); |
||||
tunnelGridLayout->addLayout(horizontalLayout_2); |
||||
|
||||
int gridIndex = 2; |
||||
{ |
||||
int port = tunnelConfig->getport(); |
||||
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); |
||||
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); |
||||
ui.portLabel = new QLabel(gridLayoutWidget_2); |
||||
portLabel->setObjectName(QStringLiteral("portLabel")); |
||||
horizontalLayout_2->addWidget(portLabel); |
||||
ui.portLineEdit = new QLineEdit(gridLayoutWidget_2); |
||||
portLineEdit->setObjectName(QStringLiteral("portLineEdit")); |
||||
portLineEdit->setText(QString::number(port)); |
||||
portLineEdit->setMaximumWidth(80); |
||||
QObject::connect(portLineEdit, SIGNAL(textChanged(const QString &)), |
||||
this, SLOT(updated())); |
||||
horizontalLayout_2->addWidget(portLineEdit); |
||||
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); |
||||
horizontalLayout_2->addItem(horizontalSpacer); |
||||
tunnelGridLayout->addLayout(horizontalLayout_2); |
||||
} |
||||
{ |
||||
std::string keys = tunnelConfig->getkeys(); |
||||
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); |
||||
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); |
||||
ui.keysLabel = new QLabel(gridLayoutWidget_2); |
||||
keysLabel->setObjectName(QStringLiteral("keysLabel")); |
||||
horizontalLayout_2->addWidget(keysLabel); |
||||
ui.keysLineEdit = new QLineEdit(gridLayoutWidget_2); |
||||
keysLineEdit->setObjectName(QStringLiteral("keysLineEdit")); |
||||
keysLineEdit->setText(keys.c_str()); |
||||
QObject::connect(keysLineEdit, SIGNAL(textChanged(const QString &)), |
||||
this, SLOT(updated())); |
||||
horizontalLayout_2->addWidget(keysLineEdit); |
||||
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); |
||||
horizontalLayout_2->addItem(horizontalSpacer); |
||||
tunnelGridLayout->addLayout(horizontalLayout_2); |
||||
} |
||||
{ |
||||
int inPort = tunnelConfig->getinPort(); |
||||
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); |
||||
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); |
||||
ui.inPortLabel = new QLabel(gridLayoutWidget_2); |
||||
inPortLabel->setObjectName(QStringLiteral("inPortLabel")); |
||||
horizontalLayout_2->addWidget(inPortLabel); |
||||
ui.inPortLineEdit = new QLineEdit(gridLayoutWidget_2); |
||||
inPortLineEdit->setObjectName(QStringLiteral("inPortLineEdit")); |
||||
inPortLineEdit->setText(QString::number(inPort)); |
||||
inPortLineEdit->setMaximumWidth(80); |
||||
QObject::connect(inPortLineEdit, SIGNAL(textChanged(const QString &)), |
||||
this, SLOT(updated())); |
||||
horizontalLayout_2->addWidget(inPortLineEdit); |
||||
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); |
||||
horizontalLayout_2->addItem(horizontalSpacer); |
||||
tunnelGridLayout->addLayout(horizontalLayout_2); |
||||
} |
||||
{ |
||||
std::string accessList = tunnelConfig->getaccessList(); |
||||
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); |
||||
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); |
||||
ui.accessListLabel = new QLabel(gridLayoutWidget_2); |
||||
accessListLabel->setObjectName(QStringLiteral("accessListLabel")); |
||||
horizontalLayout_2->addWidget(accessListLabel); |
||||
ui.accessListLineEdit = new QLineEdit(gridLayoutWidget_2); |
||||
accessListLineEdit->setObjectName(QStringLiteral("accessListLineEdit")); |
||||
accessListLineEdit->setText(accessList.c_str()); |
||||
QObject::connect(accessListLineEdit, SIGNAL(textChanged(const QString &)), |
||||
this, SLOT(updated())); |
||||
horizontalLayout_2->addWidget(accessListLineEdit); |
||||
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); |
||||
horizontalLayout_2->addItem(horizontalSpacer); |
||||
tunnelGridLayout->addLayout(horizontalLayout_2); |
||||
} |
||||
{ |
||||
std::string hostOverride = tunnelConfig->gethostOverride(); |
||||
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); |
||||
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); |
||||
ui.hostOverrideLabel = new QLabel(gridLayoutWidget_2); |
||||
hostOverrideLabel->setObjectName(QStringLiteral("hostOverrideLabel")); |
||||
horizontalLayout_2->addWidget(hostOverrideLabel); |
||||
ui.hostOverrideLineEdit = new QLineEdit(gridLayoutWidget_2); |
||||
hostOverrideLineEdit->setObjectName(QStringLiteral("hostOverrideLineEdit")); |
||||
hostOverrideLineEdit->setText(hostOverride.c_str()); |
||||
QObject::connect(hostOverrideLineEdit, SIGNAL(textChanged(const QString &)), |
||||
this, SLOT(updated())); |
||||
horizontalLayout_2->addWidget(hostOverrideLineEdit); |
||||
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); |
||||
horizontalLayout_2->addItem(horizontalSpacer); |
||||
tunnelGridLayout->addLayout(horizontalLayout_2); |
||||
} |
||||
{ |
||||
std::string webIRCPass = tunnelConfig->getwebircpass(); |
||||
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); |
||||
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); |
||||
ui.webIRCPassLabel = new QLabel(gridLayoutWidget_2); |
||||
webIRCPassLabel->setObjectName(QStringLiteral("webIRCPassLabel")); |
||||
horizontalLayout_2->addWidget(webIRCPassLabel); |
||||
ui.webIRCPassLineEdit = new QLineEdit(gridLayoutWidget_2); |
||||
webIRCPassLineEdit->setObjectName(QStringLiteral("webIRCPassLineEdit")); |
||||
webIRCPassLineEdit->setText(webIRCPass.c_str()); |
||||
QObject::connect(webIRCPassLineEdit, SIGNAL(textChanged(const QString &)), |
||||
this, SLOT(updated())); |
||||
horizontalLayout_2->addWidget(webIRCPassLineEdit); |
||||
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); |
||||
horizontalLayout_2->addItem(horizontalSpacer); |
||||
tunnelGridLayout->addLayout(horizontalLayout_2); |
||||
} |
||||
{ |
||||
bool gzip = tunnelConfig->getgzip(); |
||||
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); |
||||
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); |
||||
ui.gzipCheckBox = new QCheckBox(gridLayoutWidget_2); |
||||
gzipCheckBox->setObjectName(QStringLiteral("gzipCheckBox")); |
||||
gzipCheckBox->setChecked(gzip); |
||||
QObject::connect(gzipCheckBox, SIGNAL(stateChanged(int)), |
||||
this, SLOT(updated())); |
||||
horizontalLayout_2->addWidget(gzipCheckBox); |
||||
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); |
||||
horizontalLayout_2->addItem(horizontalSpacer); |
||||
tunnelGridLayout->addLayout(horizontalLayout_2); |
||||
} |
||||
{ |
||||
i2p::data::SigningKeyType sigType = tunnelConfig->getsigType(); |
||||
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); |
||||
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); |
||||
ui.sigTypeLabel = new QLabel(gridLayoutWidget_2); |
||||
sigTypeLabel->setObjectName(QStringLiteral("sigTypeLabel")); |
||||
horizontalLayout_2->addWidget(sigTypeLabel); |
||||
ui.sigTypeComboBox = SignatureTypeComboBoxFactory::createSignatureTypeComboBox(gridLayoutWidget_2, sigType); |
||||
sigTypeComboBox->setObjectName(QStringLiteral("sigTypeComboBox")); |
||||
QObject::connect(sigTypeComboBox, SIGNAL(currentIndexChanged(int)), |
||||
this, SLOT(updated())); |
||||
horizontalLayout_2->addWidget(sigTypeComboBox); |
||||
QPushButton * lockButton2 = new QPushButton(gridLayoutWidget_2); |
||||
horizontalLayout_2->addWidget(lockButton2); |
||||
widgetlocks.add(new widgetlock(sigTypeComboBox, lockButton2)); |
||||
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); |
||||
horizontalLayout_2->addItem(horizontalSpacer); |
||||
tunnelGridLayout->addLayout(horizontalLayout_2); |
||||
} |
||||
{ |
||||
std::string address = tunnelConfig->getaddress(); |
||||
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); |
||||
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); |
||||
ui.addressLabel = new QLabel(gridLayoutWidget_2); |
||||
addressLabel->setObjectName(QStringLiteral("addressLabel")); |
||||
horizontalLayout_2->addWidget(addressLabel); |
||||
ui.addressLineEdit = new QLineEdit(gridLayoutWidget_2); |
||||
addressLineEdit->setObjectName(QStringLiteral("addressLineEdit")); |
||||
addressLineEdit->setText(address.c_str()); |
||||
QObject::connect(addressLineEdit, SIGNAL(textChanged(const QString &)), |
||||
this, SLOT(updated())); |
||||
horizontalLayout_2->addWidget(addressLineEdit); |
||||
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); |
||||
horizontalLayout_2->addItem(horizontalSpacer); |
||||
tunnelGridLayout->addLayout(horizontalLayout_2); |
||||
} |
||||
{ |
||||
bool isUniqueLocal = tunnelConfig->getisUniqueLocal(); |
||||
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); |
||||
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); |
||||
ui.isUniqueLocalCheckBox = new QCheckBox(gridLayoutWidget_2); |
||||
isUniqueLocalCheckBox->setObjectName(QStringLiteral("isUniqueLocalCheckBox")); |
||||
isUniqueLocalCheckBox->setChecked(isUniqueLocal); |
||||
QObject::connect(gzipCheckBox, SIGNAL(stateChanged(int)), |
||||
this, SLOT(updated())); |
||||
horizontalLayout_2->addWidget(isUniqueLocalCheckBox); |
||||
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); |
||||
horizontalLayout_2->addItem(horizontalSpacer); |
||||
tunnelGridLayout->addLayout(horizontalLayout_2); |
||||
} |
||||
{ |
||||
int cryptoType = tunnelConfig->getcryptoType(); |
||||
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); |
||||
ui.cryptoTypeLabel = new QLabel(gridLayoutWidget_2); |
||||
cryptoTypeLabel->setObjectName(QStringLiteral("cryptoTypeLabel")); |
||||
horizontalLayout_2->addWidget(cryptoTypeLabel); |
||||
ui.cryptoTypeLineEdit = new QLineEdit(gridLayoutWidget_2); |
||||
cryptoTypeLineEdit->setObjectName(QStringLiteral("cryptoTypeLineEdit")); |
||||
cryptoTypeLineEdit->setText(QString::number(cryptoType)); |
||||
cryptoTypeLineEdit->setMaximumWidth(80); |
||||
QObject::connect(cryptoTypeLineEdit, SIGNAL(textChanged(const QString &)), |
||||
this, SLOT(updated())); |
||||
horizontalLayout_2->addWidget(cryptoTypeLineEdit); |
||||
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); |
||||
horizontalLayout_2->addItem(horizontalSpacer); |
||||
tunnelGridLayout->addLayout(horizontalLayout_2); |
||||
} |
||||
{ |
||||
I2CPParameters& i2cpParameters = tunnelConfig->getI2cpParameters(); |
||||
appendControlsForI2CPParameters(i2cpParameters, gridIndex); |
||||
} |
||||
|
||||
retranslateServerTunnelForm(ui); |
||||
|
||||
tunnelGridLayout->invalidate(); |
||||
|
||||
return h; |
||||
} |
||||
|
||||
void ServerTunnelPane::deleteServerTunnelForm() { |
||||
TunnelPane::deleteTunnelForm(); |
||||
delete serverTunnelNameGroupBox;//->deleteLater();
|
||||
serverTunnelNameGroupBox=nullptr; |
||||
|
||||
//gridLayoutWidget_2->deleteLater();
|
||||
//gridLayoutWidget_2=nullptr;
|
||||
} |
||||
|
||||
|
||||
ServerTunnelPane* ServerTunnelPane::asServerTunnelPane(){return this;} |
||||
ClientTunnelPane* ServerTunnelPane::asClientTunnelPane(){return nullptr;} |
@ -1,183 +0,0 @@
@@ -1,183 +0,0 @@
|
||||
#ifndef SERVERTUNNELPANE_H |
||||
#define SERVERTUNNELPANE_H |
||||
|
||||
#include <QtCore/QVariant> |
||||
#include <QtWidgets/QAction> |
||||
#include <QtWidgets/QApplication> |
||||
#include <QtWidgets/QButtonGroup> |
||||
#include <QtWidgets/QComboBox> |
||||
#include <QtWidgets/QGridLayout> |
||||
#include <QtWidgets/QGroupBox> |
||||
#include <QtWidgets/QHBoxLayout> |
||||
#include <QtWidgets/QHeaderView> |
||||
#include <QtWidgets/QLabel> |
||||
#include <QtWidgets/QLineEdit> |
||||
#include <QtWidgets/QPushButton> |
||||
#include <QtWidgets/QSpacerItem> |
||||
#include <QtWidgets/QWidget> |
||||
#include "QVBoxLayout" |
||||
#include "QCheckBox" |
||||
|
||||
#include "assert.h" |
||||
|
||||
#include "TunnelPane.h" |
||||
#include "TunnelsPageUpdateListener.h" |
||||
|
||||
class ServerTunnelConfig; |
||||
|
||||
class ClientTunnelPane; |
||||
|
||||
class ServerTunnelPane : public TunnelPane { |
||||
Q_OBJECT |
||||
|
||||
public: |
||||
ServerTunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener, ServerTunnelConfig* tunconf, QWidget* wrongInputPane_, QLabel* wrongInputLabel_, MainWindow* mainWindow); |
||||
virtual ~ServerTunnelPane(){} |
||||
|
||||
virtual ServerTunnelPane* asServerTunnelPane(); |
||||
virtual ClientTunnelPane* asClientTunnelPane(); |
||||
|
||||
int appendServerTunnelForm(ServerTunnelConfig* tunnelConfig, QWidget *tunnelsFormGridLayoutWidget, |
||||
int tunnelsRow, int height); |
||||
void deleteServerTunnelForm(); |
||||
|
||||
private: |
||||
QGroupBox *serverTunnelNameGroupBox; |
||||
|
||||
//tunnel
|
||||
QWidget *gridLayoutWidget_2; |
||||
|
||||
//host
|
||||
QHBoxLayout *horizontalLayout_2; |
||||
QLabel *hostLabel; |
||||
QLineEdit *hostLineEdit; |
||||
QSpacerItem *hostHorizontalSpacer; |
||||
|
||||
//port
|
||||
QLabel * portLabel; |
||||
QLineEdit * portLineEdit; |
||||
|
||||
//keys
|
||||
QLabel * keysLabel; |
||||
QLineEdit * keysLineEdit; |
||||
|
||||
//inPort
|
||||
QLabel * inPortLabel; |
||||
QLineEdit * inPortLineEdit; |
||||
|
||||
//cryptoType
|
||||
QLabel * cryptoTypeLabel; |
||||
QLineEdit * cryptoTypeLineEdit; |
||||
|
||||
//accessList
|
||||
QLabel * accessListLabel; |
||||
QLineEdit * accessListLineEdit; |
||||
|
||||
//hostOverride
|
||||
QLabel * hostOverrideLabel; |
||||
QLineEdit * hostOverrideLineEdit; |
||||
|
||||
//webIRCPass
|
||||
QLabel * webIRCPassLabel; |
||||
QLineEdit * webIRCPassLineEdit; |
||||
|
||||
//address
|
||||
QLabel * addressLabel; |
||||
QLineEdit * addressLineEdit; |
||||
|
||||
//gzip
|
||||
QCheckBox * gzipCheckBox; |
||||
|
||||
//isUniqueLocal
|
||||
QCheckBox * isUniqueLocalCheckBox; |
||||
|
||||
//sigType
|
||||
QLabel * sigTypeLabel; |
||||
QComboBox * sigTypeComboBox; |
||||
|
||||
protected slots: |
||||
virtual void setGroupBoxTitle(const QString & title); |
||||
|
||||
private: |
||||
void retranslateServerTunnelForm(ServerTunnelPane& /*ui*/) { |
||||
typeLabel->setText(QApplication::translate("srvTunForm", "Server tunnel type:", 0)); |
||||
hostLabel->setText(QApplication::translate("srvTunForm", "Host:", 0)); |
||||
portLabel->setText(QApplication::translate("srvTunForm", "Port:", 0)); |
||||
keysLabel->setText(QApplication::translate("srvTunForm", "Keys:", 0)); |
||||
inPortLabel->setText(QApplication::translate("srvTunForm", "InPort:", 0)); |
||||
cryptoTypeLabel->setText(QApplication::translate("srvTunForm", "Crypto type:", 0)); |
||||
accessListLabel->setText(QApplication::translate("srvTunForm", "Access list:", 0)); |
||||
hostOverrideLabel->setText(QApplication::translate("srvTunForm", "Host override:", 0)); |
||||
webIRCPassLabel->setText(QApplication::translate("srvTunForm", "WebIRC password:", 0)); |
||||
addressLabel->setText(QApplication::translate("srvTunForm", "Address:", 0)); |
||||
|
||||
gzipCheckBox->setText(QApplication::translate("srvTunForm", "GZip", 0)); |
||||
isUniqueLocalCheckBox->setText(QApplication::translate("srvTunForm", "Is unique local", 0)); |
||||
|
||||
sigTypeLabel->setText(QApplication::translate("cltTunForm", "Signature type:", 0)); |
||||
} |
||||
|
||||
protected: |
||||
virtual bool applyDataFromUIToTunnelConfig() { |
||||
QString cannotSaveSettings = QApplication::tr("Cannot save settings."); |
||||
bool ok=TunnelPane::applyDataFromUIToTunnelConfig(); |
||||
if(!ok)return false; |
||||
ServerTunnelConfig* stc=tunnelConfig->asServerTunnelConfig(); |
||||
assert(stc!=nullptr); |
||||
|
||||
if(!isValidSingleLine(hostLineEdit))return false; |
||||
if(!isValidSingleLine(portLineEdit))return false; |
||||
if(!isValidSingleLine(cryptoTypeLineEdit))return false; |
||||
if(!isValidSingleLine(keysLineEdit))return false; |
||||
if(!isValidSingleLine(inPortLineEdit))return false; |
||||
if(!isValidSingleLine(accessListLineEdit))return false; |
||||
if(!isValidSingleLine(hostOverrideLineEdit))return false; |
||||
if(!isValidSingleLine(webIRCPassLineEdit))return false; |
||||
if(!isValidSingleLine(addressLineEdit))return false; |
||||
|
||||
stc->sethost(hostLineEdit->text().toStdString()); |
||||
|
||||
auto portStr=portLineEdit->text(); |
||||
int portInt=portStr.toInt(&ok); |
||||
if(!ok){ |
||||
highlightWrongInput(QApplication::tr("Bad port, must be int.")+" "+cannotSaveSettings,portLineEdit); |
||||
return false; |
||||
} |
||||
stc->setport(portInt); |
||||
|
||||
auto cryptoTypeStr=cryptoTypeLineEdit->text(); |
||||
int cryptoTypeInt=cryptoTypeStr.toInt(&ok); |
||||
if(!ok){ |
||||
highlightWrongInput(QApplication::tr("Bad crypto type, must be int.")+" "+cannotSaveSettings,cryptoTypeLineEdit); |
||||
return false; |
||||
} |
||||
stc->setcryptoType(cryptoTypeInt); |
||||
|
||||
stc->setkeys(keysLineEdit->text().toStdString()); |
||||
|
||||
auto str=inPortLineEdit->text(); |
||||
int inPortInt=str.toInt(&ok); |
||||
if(!ok){ |
||||
highlightWrongInput(QApplication::tr("Bad inPort, must be int.")+" "+cannotSaveSettings,inPortLineEdit); |
||||
return false; |
||||
} |
||||
stc->setinPort(inPortInt); |
||||
|
||||
stc->setaccessList(accessListLineEdit->text().toStdString()); |
||||
|
||||
stc->sethostOverride(hostOverrideLineEdit->text().toStdString()); |
||||
|
||||
stc->setwebircpass(webIRCPassLineEdit->text().toStdString()); |
||||
|
||||
stc->setaddress(addressLineEdit->text().toStdString()); |
||||
|
||||
stc->setgzip(gzipCheckBox->isChecked()); |
||||
|
||||
stc->setisUniqueLocal(isUniqueLocalCheckBox->isChecked()); |
||||
|
||||
stc->setsigType(readSigTypeComboboxUI(sigTypeComboBox)); |
||||
return true; |
||||
} |
||||
}; |
||||
|
||||
#endif // SERVERTUNNELPANE_H
|
@ -1,2 +0,0 @@
@@ -1,2 +0,0 @@
|
||||
#include "SignatureTypeComboboxFactory.h" |
||||
|
@ -1,86 +0,0 @@
@@ -1,86 +0,0 @@
|
||||
#ifndef SIGNATURETYPECOMBOBOXFACTORY_H |
||||
#define SIGNATURETYPECOMBOBOXFACTORY_H |
||||
|
||||
#include <QApplication> |
||||
#include <QComboBox> |
||||
#include <QWidget> |
||||
#include "Identity.h" |
||||
|
||||
class SignatureTypeComboBoxFactory |
||||
{ |
||||
static const QVariant createUserData(const uint16_t sigType) { |
||||
return QVariant::fromValue((uint)sigType); |
||||
} |
||||
|
||||
static void addItem(QComboBox* signatureTypeCombobox, QString text, const uint16_t sigType) { |
||||
const QVariant userData = createUserData(sigType); |
||||
signatureTypeCombobox->addItem(text, userData); |
||||
} |
||||
|
||||
public: |
||||
static uint16_t getSigType(const QVariant& var) { |
||||
return (uint16_t)var.toInt(); |
||||
} |
||||
|
||||
static void fillComboBox(QComboBox* signatureTypeCombobox, uint16_t selectedSigType) { |
||||
/*
|
||||
<orignal> https://geti2p.net/spec/common-structures#certificate
|
||||
<orignal> все коды перечислены |
||||
<Hypnosis> это таблица "The defined Signing Public Key types are:" ? |
||||
<orignal> да |
||||
|
||||
see also: Identity.h line 55 |
||||
*/ |
||||
int index=0; |
||||
bool foundSelected=false; |
||||
|
||||
using namespace i2p::data; |
||||
|
||||
addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "DSA_SHA1", 0), SIGNING_KEY_TYPE_DSA_SHA1); //0
|
||||
if(selectedSigType==SIGNING_KEY_TYPE_DSA_SHA1){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;} |
||||
++index; |
||||
addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "ECDSA_SHA256_P256", 0), SIGNING_KEY_TYPE_ECDSA_SHA256_P256); //1
|
||||
if(selectedSigType==SIGNING_KEY_TYPE_ECDSA_SHA256_P256){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;} |
||||
++index; |
||||
addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "ECDSA_SHA384_P384", 0), SIGNING_KEY_TYPE_ECDSA_SHA384_P384); //2
|
||||
if(selectedSigType==SIGNING_KEY_TYPE_ECDSA_SHA384_P384){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;} |
||||
++index; |
||||
addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "ECDSA_SHA512_P521", 0), SIGNING_KEY_TYPE_ECDSA_SHA512_P521); //3
|
||||
if(selectedSigType==SIGNING_KEY_TYPE_ECDSA_SHA512_P521){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;} |
||||
++index; |
||||
addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "RSA_SHA256_2048", 0), SIGNING_KEY_TYPE_RSA_SHA256_2048); //4
|
||||
if(selectedSigType==SIGNING_KEY_TYPE_RSA_SHA256_2048){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;} |
||||
++index; |
||||
addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "RSA_SHA384_3072", 0), SIGNING_KEY_TYPE_RSA_SHA384_3072); //5
|
||||
if(selectedSigType==SIGNING_KEY_TYPE_RSA_SHA384_3072){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;} |
||||
++index; |
||||
addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "RSA_SHA512_4096", 0), SIGNING_KEY_TYPE_RSA_SHA512_4096); //6
|
||||
if(selectedSigType==SIGNING_KEY_TYPE_RSA_SHA512_4096){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;} |
||||
++index; |
||||
addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "EDDSA_SHA512_ED25519", 0), SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519); //7
|
||||
if(selectedSigType==SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;} |
||||
++index; |
||||
addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "EDDSA_SHA512_ED25519PH", 0), SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519ph); //8
|
||||
if(selectedSigType==SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519ph){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;} |
||||
++index; |
||||
// the following signature type should never appear in netid=2
|
||||
addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "GOSTR3410_CRYPTO_PRO_A_GOSTR3411_256", 0), SIGNING_KEY_TYPE_GOSTR3410_CRYPTO_PRO_A_GOSTR3411_256); //9
|
||||
if(selectedSigType==SIGNING_KEY_TYPE_GOSTR3410_CRYPTO_PRO_A_GOSTR3411_256){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;} |
||||
++index; |
||||
addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "GOSTR3410_TC26_A_512_GOSTR3411_512", 0), SIGNING_KEY_TYPE_GOSTR3410_TC26_A_512_GOSTR3411_512); //10
|
||||
if(selectedSigType==SIGNING_KEY_TYPE_GOSTR3410_TC26_A_512_GOSTR3411_512){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;} |
||||
++index; |
||||
if(!foundSelected){ |
||||
addItem(signatureTypeCombobox, QString::number(selectedSigType), selectedSigType); //unknown sigtype
|
||||
signatureTypeCombobox->setCurrentIndex(index); |
||||
} |
||||
} |
||||
|
||||
static QComboBox* createSignatureTypeComboBox(QWidget* parent, uint16_t selectedSigType) { |
||||
QComboBox* signatureTypeCombobox = new QComboBox(parent); |
||||
fillComboBox(signatureTypeCombobox, selectedSigType); |
||||
return signatureTypeCombobox; |
||||
} |
||||
}; |
||||
|
||||
#endif // SIGNATURETYPECOMBOBOXFACTORY_H
|
@ -1,67 +0,0 @@
@@ -1,67 +0,0 @@
|
||||
#include "TunnelConfig.h" |
||||
|
||||
void TunnelConfig::saveHeaderToStringStream(std::stringstream& out) { |
||||
out << "[" << name << "]\n" |
||||
<< "type=" << type.toStdString() << "\n"; |
||||
} |
||||
|
||||
void TunnelConfig::saveI2CPParametersToStringStream(std::stringstream& out) { |
||||
if (i2cpParameters.getInbound_length().toUShort() != i2p::client::DEFAULT_INBOUND_TUNNEL_LENGTH) |
||||
out << i2p::client::I2CP_PARAM_INBOUND_TUNNEL_LENGTH << "=" |
||||
<< i2cpParameters.getInbound_length().toStdString() << "\n"; |
||||
if (i2cpParameters.getOutbound_length().toUShort() != i2p::client::DEFAULT_OUTBOUND_TUNNEL_LENGTH) |
||||
out << i2p::client::I2CP_PARAM_OUTBOUND_TUNNEL_LENGTH << "=" |
||||
<< i2cpParameters.getOutbound_length().toStdString() << "\n"; |
||||
if (i2cpParameters.getInbound_quantity().toUShort() != i2p::client::DEFAULT_INBOUND_TUNNELS_QUANTITY) |
||||
out << i2p::client::I2CP_PARAM_INBOUND_TUNNELS_QUANTITY << "=" |
||||
<< i2cpParameters.getInbound_quantity().toStdString() << "\n"; |
||||
if (i2cpParameters.getOutbound_quantity().toUShort() != i2p::client::DEFAULT_OUTBOUND_TUNNELS_QUANTITY) |
||||
out << i2p::client::I2CP_PARAM_OUTBOUND_TUNNELS_QUANTITY << "=" |
||||
<< i2cpParameters.getOutbound_quantity().toStdString() << "\n"; |
||||
if (i2cpParameters.getCrypto_tagsToSend().toUShort() != i2p::client::DEFAULT_TAGS_TO_SEND) |
||||
out << i2p::client::I2CP_PARAM_TAGS_TO_SEND << "=" |
||||
<< i2cpParameters.getCrypto_tagsToSend().toStdString() << "\n"; |
||||
if (!i2cpParameters.getExplicitPeers().isEmpty()) //todo #947
|
||||
out << i2p::client::I2CP_PARAM_EXPLICIT_PEERS << "=" |
||||
<< i2cpParameters.getExplicitPeers().toStdString() << "\n"; |
||||
out << i2p::client::I2CP_PARAM_LEASESET_AUTH_TYPE << "=" |
||||
<< i2cpParameters.get_i2cp_leaseSetAuthType().toStdString() << "\n"; |
||||
out << i2p::client::I2CP_PARAM_LEASESET_ENCRYPTION_TYPE << "=" |
||||
<< i2cpParameters.get_i2cp_leaseSetEncType().toStdString() << "\n"; |
||||
out << i2p::client::I2CP_PARAM_LEASESET_PRIV_KEY << "=" |
||||
<< i2cpParameters.get_i2cp_leaseSetPrivKey().toStdString() << "\n"; |
||||
out << i2p::client::I2CP_PARAM_LEASESET_TYPE << "=" |
||||
<< i2cpParameters.get_i2cp_leaseSetType().toStdString() << "\n"; |
||||
out << i2p::client::I2CP_PARAM_STREAMING_ANSWER_PINGS << "=" |
||||
<< (i2cpParameters.get_i2p_streaming_answerPings() ? "true" : "false") << "\n"; |
||||
out << i2p::client::I2CP_PARAM_STREAMING_INITIAL_ACK_DELAY << "=" |
||||
<< i2cpParameters.get_i2p_streaming_initialAckDelay().toStdString() << "\n"; |
||||
out << "\n"; |
||||
} |
||||
|
||||
void ClientTunnelConfig::saveToStringStream(std::stringstream& out) { |
||||
out << "address=" << address << "\n" |
||||
<< "port=" << port << "\n" |
||||
<< "destination=" << dest << "\n" |
||||
<< "destinationport=" << destinationPort << "\n" |
||||
<< "cryptoType=" << getcryptoType() << "\n" |
||||
<< "signaturetype=" << sigType << "\n"; |
||||
if(!keys.empty()) out << "keys=" << keys << "\n"; |
||||
} |
||||
|
||||
|
||||
void ServerTunnelConfig::saveToStringStream(std::stringstream& out) { |
||||
out << "host=" << host << "\n" |
||||
<< "port=" << port << "\n" |
||||
<< "signaturetype=" << sigType << "\n" |
||||
<< "inport=" << inPort << "\n"; |
||||
if(accessList.size()>0) { out << "accesslist=" << accessList << "\n"; } |
||||
out << "gzip=" << (gzip?"true":"false") << "\n" |
||||
<< "cryptoType=" << getcryptoType() << "\n" |
||||
<< "enableuniquelocal=" << (isUniqueLocal?"true":"false") << "\n" |
||||
<< "address=" << address << "\n" |
||||
<< "hostoverride=" << hostOverride << "\n" |
||||
<< "webircpassword=" << webircpass << "\n"; |
||||
if(!keys.empty()) out << "keys=" << keys << "\n"; |
||||
} |
||||
|
@ -1,260 +0,0 @@
@@ -1,260 +0,0 @@
|
||||
#ifndef TUNNELCONFIG_H |
||||
#define TUNNELCONFIG_H |
||||
|
||||
#include "QString" |
||||
#include <string> |
||||
|
||||
#include "../../libi2pd_client/ClientContext.h" |
||||
#include "../../libi2pd/Destination.h" |
||||
#include "TunnelsPageUpdateListener.h" |
||||
|
||||
|
||||
class I2CPParameters{ |
||||
QString inbound_length;//number of hops of an inbound tunnel. 3 by default; lower value is faster but dangerous
|
||||
QString outbound_length;//number of hops of an outbound tunnel. 3 by default; lower value is faster but dangerous
|
||||
QString inbound_quantity; //number of inbound tunnels. 5 by default
|
||||
QString outbound_quantity; //number of outbound tunnels. 5 by default
|
||||
QString crypto_tagsToSend; //number of ElGamal/AES tags to send. 40 by default; too low value may cause problems with tunnel building
|
||||
QString explicitPeers; //list of comma-separated b64 addresses of peers to use, default: unset
|
||||
QString i2p_streaming_initialAckDelay; //i2p.streaming.initialAckDelay -- milliseconds to wait before sending Ack. 200 by default
|
||||
bool i2p_streaming_answerPings; //i2p.streaming.answerPings -- enable sending pongs. true by default
|
||||
QString i2cp_leaseSetType; //i2cp.leaseSetType -- type of LeaseSet to be sent. 1, 3 or 5. 1 by default
|
||||
QString i2cp_leaseSetEncType; //i2cp.leaseSetEncType -- comma separated encryption types to be used in LeaseSet type 3 or 5. Identity's type by default
|
||||
QString i2cp_leaseSetPrivKey; //i2cp.leaseSetPrivKey -- decryption key for encrypted LeaseSet in base64. PSK or private DH
|
||||
QString i2cp_leaseSetAuthType; //i2cp.leaseSetAuthType -- authentication type for encrypted LeaseSet. 0 - no authentication(default), 1 - DH, 2 - PSK
|
||||
public: |
||||
I2CPParameters(): inbound_length(), |
||||
outbound_length(), |
||||
inbound_quantity(), |
||||
outbound_quantity(), |
||||
crypto_tagsToSend(), |
||||
explicitPeers(), |
||||
i2p_streaming_initialAckDelay(), |
||||
i2p_streaming_answerPings(true), |
||||
i2cp_leaseSetType(), |
||||
i2cp_leaseSetEncType(), |
||||
i2cp_leaseSetPrivKey(), |
||||
i2cp_leaseSetAuthType() {} |
||||
const QString& getInbound_length(){return inbound_length;} |
||||
const QString& getOutbound_length(){return outbound_length;} |
||||
const QString& getInbound_quantity(){return inbound_quantity;} |
||||
const QString& getOutbound_quantity(){return outbound_quantity;} |
||||
const QString& getCrypto_tagsToSend(){return crypto_tagsToSend;} |
||||
const QString& getExplicitPeers(){return explicitPeers;} |
||||
const QString& get_i2p_streaming_initialAckDelay(){return i2p_streaming_initialAckDelay;} |
||||
bool get_i2p_streaming_answerPings(){return i2p_streaming_answerPings;} |
||||
const QString& get_i2cp_leaseSetType(){return i2cp_leaseSetType;} |
||||
const QString& get_i2cp_leaseSetEncType(){return i2cp_leaseSetEncType;} |
||||
const QString& get_i2cp_leaseSetPrivKey(){return i2cp_leaseSetPrivKey;} |
||||
const QString& get_i2cp_leaseSetAuthType(){return i2cp_leaseSetAuthType;} |
||||
void setInbound_length(QString inbound_length_){inbound_length=inbound_length_;} |
||||
void setOutbound_length(QString outbound_length_){outbound_length=outbound_length_;} |
||||
void setInbound_quantity(QString inbound_quantity_){inbound_quantity=inbound_quantity_;} |
||||
void setOutbound_quantity(QString outbound_quantity_){outbound_quantity=outbound_quantity_;} |
||||
void setCrypto_tagsToSend(QString crypto_tagsToSend_){crypto_tagsToSend=crypto_tagsToSend_;} |
||||
void setExplicitPeers(QString explicitPeers_){explicitPeers=explicitPeers_;} |
||||
void set_i2p_streaming_initialAckDelay(QString i2p_streaming_initialAckDelay_){i2p_streaming_initialAckDelay=i2p_streaming_initialAckDelay_;} |
||||
void set_i2p_streaming_answerPings(bool i2p_streaming_answerPings_){i2p_streaming_answerPings=i2p_streaming_answerPings_;} |
||||
void set_i2cp_leaseSetType(QString i2cp_leaseSetType_){i2cp_leaseSetType=i2cp_leaseSetType_;} |
||||
void set_i2cp_leaseSetEncType(QString i2cp_leaseSetEncType_){i2cp_leaseSetEncType=i2cp_leaseSetEncType_;} |
||||
void set_i2cp_leaseSetPrivKey(QString i2cp_leaseSetPrivKey_){i2cp_leaseSetPrivKey=i2cp_leaseSetPrivKey_;} |
||||
void set_i2cp_leaseSetAuthType(QString i2cp_leaseSetAuthType_){i2cp_leaseSetAuthType=i2cp_leaseSetAuthType_;} |
||||
}; |
||||
|
||||
|
||||
class ClientTunnelConfig; |
||||
class ServerTunnelConfig; |
||||
|
||||
class TunnelPane; |
||||
|
||||
class TunnelConfig { |
||||
/*
|
||||
const char I2P_TUNNELS_SECTION_TYPE_CLIENT[] = "client"; |
||||
const char I2P_TUNNELS_SECTION_TYPE_SERVER[] = "server"; |
||||
const char I2P_TUNNELS_SECTION_TYPE_HTTP[] = "http"; |
||||
const char I2P_TUNNELS_SECTION_TYPE_IRC[] = "irc"; |
||||
const char I2P_TUNNELS_SECTION_TYPE_UDPCLIENT[] = "udpclient"; |
||||
const char I2P_TUNNELS_SECTION_TYPE_UDPSERVER[] = "udpserver"; |
||||
const char I2P_TUNNELS_SECTION_TYPE_SOCKS[] = "socks"; |
||||
const char I2P_TUNNELS_SECTION_TYPE_WEBSOCKS[] = "websocks"; |
||||
const char I2P_TUNNELS_SECTION_TYPE_HTTPPROXY[] = "httpproxy"; |
||||
*/ |
||||
QString type; |
||||
std::string name; |
||||
TunnelPane* tunnelPane; |
||||
int cryptoType; |
||||
public: |
||||
TunnelConfig(std::string name_, QString& type_, I2CPParameters& i2cpParameters_, int cryptoType_): |
||||
type(type_), name(name_), cryptoType(cryptoType_), i2cpParameters(i2cpParameters_) {} |
||||
virtual ~TunnelConfig(){} |
||||
const QString& getType(){return type;} |
||||
const std::string& getName(){return name;} |
||||
int getcryptoType(){return cryptoType;} |
||||
void setType(const QString& type_){type=type_;} |
||||
void setName(const std::string& name_){name=name_;} |
||||
I2CPParameters& getI2cpParameters(){return i2cpParameters;} |
||||
void saveHeaderToStringStream(std::stringstream& out); |
||||
void saveI2CPParametersToStringStream(std::stringstream& out); |
||||
virtual void saveToStringStream(std::stringstream& out)=0; |
||||
virtual ClientTunnelConfig* asClientTunnelConfig()=0; |
||||
virtual ServerTunnelConfig* asServerTunnelConfig()=0; |
||||
void setTunnelPane(TunnelPane* tp){this->tunnelPane = tp;} |
||||
TunnelPane* getTunnelPane() {return tunnelPane;} |
||||
void setcryptoType(int cryptoType_){cryptoType=cryptoType_;} |
||||
private: |
||||
I2CPParameters i2cpParameters; |
||||
}; |
||||
|
||||
/*
|
||||
# mandatory parameters: |
||||
std::string dest; |
||||
if (type == I2P_TUNNELS_SECTION_TYPE_CLIENT || type == I2P_TUNNELS_SECTION_TYPE_UDPCLIENT) |
||||
dest = section.second.get<std::string> (I2P_CLIENT_TUNNEL_DESTINATION); |
||||
int port = section.second.get<int> (I2P_CLIENT_TUNNEL_PORT); |
||||
# optional parameters (may be omitted) |
||||
std::string keys = section.second.get (I2P_CLIENT_TUNNEL_KEYS, ""); |
||||
std::string address = section.second.get (I2P_CLIENT_TUNNEL_ADDRESS, "127.0.0.1"); |
||||
int destinationPort = section.second.get (I2P_CLIENT_TUNNEL_DESTINATION_PORT, 0); |
||||
i2p::data::SigningKeyType sigType = section.second.get (I2P_CLIENT_TUNNEL_SIGNATURE_TYPE, i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256); |
||||
# * keys -- our identity, if unset, will be generated on every startup, |
||||
# if set and file missing, keys will be generated and placed to this file |
||||
# * address -- local interface to bind |
||||
# * signaturetype -- signature type for new destination. 0 (DSA/SHA1), 1 (EcDSA/SHA256) or 7 (EdDSA/SHA512) |
||||
[somelabel] |
||||
type = client |
||||
address = 127.0.0.1 |
||||
port = 6668 |
||||
destination = irc.postman.i2p |
||||
keys = irc-keys.dat |
||||
*/ |
||||
class ClientTunnelConfig : public TunnelConfig { |
||||
std::string dest; |
||||
int port; |
||||
std::string keys; |
||||
std::string address; |
||||
int destinationPort; |
||||
i2p::data::SigningKeyType sigType; |
||||
public: |
||||
ClientTunnelConfig(std::string name_, QString type_, I2CPParameters& i2cpParameters_, |
||||
std::string dest_, |
||||
int port_, |
||||
std::string keys_, |
||||
std::string address_, |
||||
int destinationPort_, |
||||
i2p::data::SigningKeyType sigType_, |
||||
int cryptoType_): TunnelConfig(name_, type_, i2cpParameters_, cryptoType_), |
||||
dest(dest_), |
||||
port(port_), |
||||
keys(keys_), |
||||
address(address_), |
||||
destinationPort(destinationPort_), |
||||
sigType(sigType_) {} |
||||
std::string& getdest(){return dest;} |
||||
int getport(){return port;} |
||||
std::string & getkeys(){return keys;} |
||||
std::string & getaddress(){return address;} |
||||
int getdestinationPort(){return destinationPort;} |
||||
i2p::data::SigningKeyType getsigType(){return sigType;} |
||||
void setdest(const std::string& dest_){dest=dest_;} |
||||
void setport(int port_){port=port_;} |
||||
void setkeys(const std::string & keys_){keys=keys_;} |
||||
void setaddress(const std::string & address_){address=address_;} |
||||
void setdestinationPort(int destinationPort_){destinationPort=destinationPort_;} |
||||
void setsigType(i2p::data::SigningKeyType sigType_){sigType=sigType_;} |
||||
virtual void saveToStringStream(std::stringstream& out); |
||||
virtual ClientTunnelConfig* asClientTunnelConfig(){return this;} |
||||
virtual ServerTunnelConfig* asServerTunnelConfig(){return nullptr;} |
||||
}; |
||||
|
||||
/*
|
||||
# mandatory parameters: |
||||
# * host -- ip address of our service |
||||
# * port -- port of our service |
||||
# * keys -- file with LeaseSet of address in i2p |
||||
std::string host = section.second.get<std::string> (I2P_SERVER_TUNNEL_HOST); |
||||
int port = section.second.get<int> (I2P_SERVER_TUNNEL_PORT); |
||||
std::string keys = section.second.get<std::string> (I2P_SERVER_TUNNEL_KEYS); |
||||
# optional parameters (may be omitted) |
||||
int inPort = section.second.get (I2P_SERVER_TUNNEL_INPORT, 0); |
||||
std::string accessList = section.second.get (I2P_SERVER_TUNNEL_ACCESS_LIST, ""); |
||||
std::string hostOverride = section.second.get (I2P_SERVER_TUNNEL_HOST_OVERRIDE, ""); |
||||
std::string webircpass = section.second.get<std::string> (I2P_SERVER_TUNNEL_WEBIRC_PASSWORD, ""); |
||||
bool gzip = section.second.get (I2P_SERVER_TUNNEL_GZIP, true); |
||||
i2p::data::SigningKeyType sigType = section.second.get (I2P_SERVER_TUNNEL_SIGNATURE_TYPE, i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256); |
||||
std::string address = section.second.get<std::string> (I2P_SERVER_TUNNEL_ADDRESS, "127.0.0.1"); |
||||
bool isUniqueLocal = section.second.get(I2P_SERVER_TUNNEL_ENABLE_UNIQUE_LOCAL, true); |
||||
# * inport -- optional, i2p service port, if unset - the same as 'port' |
||||
# * accesslist -- comma-separated list of i2p addresses, allowed to connect |
||||
# every address is b32 without '.b32.i2p' part |
||||
[somelabel] |
||||
type = server |
||||
host = 127.0.0.1 |
||||
port = 6667 |
||||
keys = irc.dat |
||||
*/ |
||||
class ServerTunnelConfig : public TunnelConfig { |
||||
std::string host; |
||||
int port; |
||||
std::string keys; |
||||
int inPort; |
||||
std::string accessList; |
||||
std::string hostOverride; |
||||
std::string webircpass; |
||||
bool gzip; |
||||
i2p::data::SigningKeyType sigType; |
||||
std::string address; |
||||
bool isUniqueLocal; |
||||
public: |
||||
ServerTunnelConfig(std::string name_, QString type_, I2CPParameters& i2cpParameters_, |
||||
std::string host_, |
||||
int port_, |
||||
std::string keys_, |
||||
int inPort_, |
||||
std::string accessList_, |
||||
std::string hostOverride_, |
||||
std::string webircpass_, |
||||
bool gzip_, |
||||
i2p::data::SigningKeyType sigType_, |
||||
std::string address_, |
||||
bool isUniqueLocal_, |
||||
int cryptoType_): TunnelConfig(name_, type_, i2cpParameters_, cryptoType_), |
||||
host(host_), |
||||
port(port_), |
||||
keys(keys_), |
||||
inPort(inPort_), |
||||
accessList(accessList_), |
||||
hostOverride(hostOverride_), |
||||
webircpass(webircpass_), |
||||
gzip(gzip_), |
||||
sigType(sigType_), |
||||
address(address_), |
||||
isUniqueLocal(isUniqueLocal_) {} |
||||
std::string& gethost(){return host;} |
||||
int getport(){return port;} |
||||
std::string& getkeys(){return keys;} |
||||
int getinPort(){return inPort;} |
||||
std::string& getaccessList(){return accessList;} |
||||
std::string& gethostOverride(){return hostOverride;} |
||||
std::string& getwebircpass(){return webircpass;} |
||||
bool getgzip(){return gzip;} |
||||
i2p::data::SigningKeyType getsigType(){return sigType;} |
||||
std::string& getaddress(){return address;} |
||||
bool getisUniqueLocal(){return isUniqueLocal;} |
||||
void sethost(const std::string& host_){host=host_;} |
||||
void setport(int port_){port=port_;} |
||||
void setkeys(const std::string& keys_){keys=keys_;} |
||||
void setinPort(int inPort_){inPort=inPort_;} |
||||
void setaccessList(const std::string& accessList_){accessList=accessList_;} |
||||
void sethostOverride(const std::string& hostOverride_){hostOverride=hostOverride_;} |
||||
void setwebircpass(const std::string& webircpass_){webircpass=webircpass_;} |
||||
void setgzip(bool gzip_){gzip=gzip_;} |
||||
void setsigType(i2p::data::SigningKeyType sigType_){sigType=sigType_;} |
||||
void setaddress(const std::string& address_){address=address_;} |
||||
void setisUniqueLocal(bool isUniqueLocal_){isUniqueLocal=isUniqueLocal_;} |
||||
virtual void saveToStringStream(std::stringstream& out); |
||||
virtual ClientTunnelConfig* asClientTunnelConfig(){return nullptr;} |
||||
virtual ServerTunnelConfig* asServerTunnelConfig(){return this;} |
||||
}; |
||||
|
||||
|
||||
#endif // TUNNELCONFIG_H
|
@ -1,405 +0,0 @@
@@ -1,405 +0,0 @@
|
||||
#include "TunnelPane.h" |
||||
|
||||
#include "QMessageBox" |
||||
#include "mainwindow.h" |
||||
#include "ui_mainwindow.h" |
||||
|
||||
#include "I2pdQtUtil.h" |
||||
|
||||
TunnelPane::TunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener_, TunnelConfig* tunnelConfig_, QWidget* wrongInputPane_, QLabel* wrongInputLabel_, MainWindow* mainWindow_): |
||||
QObject(), |
||||
mainWindow(mainWindow_), |
||||
wrongInputPane(wrongInputPane_), |
||||
wrongInputLabel(wrongInputLabel_), |
||||
tunnelConfig(tunnelConfig_), |
||||
tunnelsPageUpdateListener(tunnelsPageUpdateListener_), |
||||
gridLayoutWidget_2(nullptr) {} |
||||
|
||||
void TunnelPane::setupTunnelPane( |
||||
TunnelConfig* tunnelConfig, |
||||
QGroupBox *tunnelGroupBox, |
||||
QWidget* gridLayoutWidget_2, QComboBox * tunnelTypeComboBox, |
||||
QWidget *tunnelsFormGridLayoutWidget, int tunnelsRow, int height, int h) { |
||||
tunnelGroupBox->setGeometry(0, tunnelsFormGridLayoutWidget->height(), gridLayoutWidget_2->width(), h); |
||||
tunnelsFormGridLayoutWidget->resize(527, tunnelsFormGridLayoutWidget->height()+h); |
||||
|
||||
QObject::connect(tunnelTypeComboBox, SIGNAL(currentIndexChanged(int)), |
||||
this, SLOT(updated())); |
||||
|
||||
|
||||
this->tunnelGroupBox=tunnelGroupBox; |
||||
|
||||
gridLayoutWidget_2->setObjectName(QStringLiteral("gridLayoutWidget_2")); |
||||
this->gridLayoutWidget_2=gridLayoutWidget_2; |
||||
tunnelGridLayout = new QVBoxLayout(gridLayoutWidget_2); |
||||
tunnelGridLayout->setObjectName(QStringLiteral("tunnelGridLayout")); |
||||
tunnelGridLayout->setContentsMargins(10, 25, 10, 10); |
||||
tunnelGridLayout->setSpacing(5); |
||||
|
||||
//header
|
||||
QHBoxLayout *headerHorizontalLayout = new QHBoxLayout(); |
||||
headerHorizontalLayout->setObjectName(QStringLiteral("headerHorizontalLayout")); |
||||
|
||||
nameLabel = new QLabel(gridLayoutWidget_2); |
||||
nameLabel->setObjectName(QStringLiteral("nameLabel")); |
||||
headerHorizontalLayout->addWidget(nameLabel); |
||||
nameLineEdit = new QLineEdit(gridLayoutWidget_2); |
||||
nameLineEdit->setObjectName(QStringLiteral("nameLineEdit")); |
||||
const QString& tunnelName=tunnelConfig->getName().c_str(); |
||||
nameLineEdit->setText(tunnelName); |
||||
setGroupBoxTitle(tunnelName); |
||||
|
||||
QObject::connect(nameLineEdit, SIGNAL(textChanged(const QString &)), |
||||
this, SLOT(updated())); |
||||
|
||||
headerHorizontalLayout->addWidget(nameLineEdit); |
||||
headerHorizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); |
||||
headerHorizontalLayout->addItem(headerHorizontalSpacer); |
||||
deletePushButton = new QPushButton(gridLayoutWidget_2); |
||||
deletePushButton->setObjectName(QStringLiteral("deletePushButton")); |
||||
QObject::connect(deletePushButton, SIGNAL(released()), |
||||
this, SLOT(deleteButtonReleased()));//MainWindow::DeleteTunnelNamed(std::string name) {
|
||||
headerHorizontalLayout->addWidget(deletePushButton); |
||||
tunnelGridLayout->addLayout(headerHorizontalLayout); |
||||
|
||||
//type
|
||||
{ |
||||
//const QString& type = tunnelConfig->getType();
|
||||
QHBoxLayout * horizontalLayout_ = new QHBoxLayout(); |
||||
horizontalLayout_->setObjectName(QStringLiteral("horizontalLayout_")); |
||||
typeLabel = new QLabel(gridLayoutWidget_2); |
||||
typeLabel->setObjectName(QStringLiteral("typeLabel")); |
||||
horizontalLayout_->addWidget(typeLabel); |
||||
horizontalLayout_->addWidget(tunnelTypeComboBox); |
||||
QPushButton * lockButton1 = new QPushButton(gridLayoutWidget_2); |
||||
horizontalLayout_->addWidget(lockButton1); |
||||
widgetlocks.add(new widgetlock(tunnelTypeComboBox, lockButton1)); |
||||
this->tunnelTypeComboBox=tunnelTypeComboBox; |
||||
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); |
||||
horizontalLayout_->addItem(horizontalSpacer); |
||||
tunnelGridLayout->addLayout(horizontalLayout_); |
||||
} |
||||
|
||||
retranslateTunnelForm(*this); |
||||
} |
||||
|
||||
void TunnelPane::deleteWidget() { |
||||
//gridLayoutWidget_2->deleteLater();
|
||||
tunnelGroupBox->deleteLater(); |
||||
} |
||||
|
||||
void TunnelPane::appendControlsForI2CPParameters(I2CPParameters& i2cpParameters, int& gridIndex) { |
||||
{ |
||||
//number of hops of an inbound tunnel
|
||||
const QString& inbound_length=i2cpParameters.getInbound_length(); |
||||
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); |
||||
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); |
||||
inbound_lengthLabel = new QLabel(gridLayoutWidget_2); |
||||
inbound_lengthLabel->setObjectName(QStringLiteral("inbound_lengthLabel")); |
||||
horizontalLayout_2->addWidget(inbound_lengthLabel); |
||||
inbound_lengthLineEdit = new QLineEdit(gridLayoutWidget_2); |
||||
inbound_lengthLineEdit->setObjectName(QStringLiteral("inbound_lengthLineEdit")); |
||||
inbound_lengthLineEdit->setText(inbound_length); |
||||
inbound_lengthLineEdit->setMaximumWidth(80); |
||||
QObject::connect(inbound_lengthLineEdit, SIGNAL(textChanged(const QString &)), |
||||
this, SLOT(updated())); |
||||
horizontalLayout_2->addWidget(inbound_lengthLineEdit); |
||||
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); |
||||
horizontalLayout_2->addItem(horizontalSpacer); |
||||
tunnelGridLayout->addLayout(horizontalLayout_2); |
||||
} |
||||
{ |
||||
//number of hops of an outbound tunnel
|
||||
const QString& outbound_length=i2cpParameters.getOutbound_length(); |
||||
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); |
||||
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); |
||||
outbound_lengthLabel = new QLabel(gridLayoutWidget_2); |
||||
outbound_lengthLabel->setObjectName(QStringLiteral("outbound_lengthLabel")); |
||||
horizontalLayout_2->addWidget(outbound_lengthLabel); |
||||
outbound_lengthLineEdit = new QLineEdit(gridLayoutWidget_2); |
||||
outbound_lengthLineEdit->setObjectName(QStringLiteral("outbound_lengthLineEdit")); |
||||
outbound_lengthLineEdit->setText(outbound_length); |
||||
outbound_lengthLineEdit->setMaximumWidth(80); |
||||
QObject::connect(outbound_lengthLineEdit, SIGNAL(textChanged(const QString &)), |
||||
this, SLOT(updated())); |
||||
horizontalLayout_2->addWidget(outbound_lengthLineEdit); |
||||
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); |
||||
horizontalLayout_2->addItem(horizontalSpacer); |
||||
tunnelGridLayout->addLayout(horizontalLayout_2); |
||||
} |
||||
{ |
||||
//number of inbound tunnels
|
||||
const QString& inbound_quantity=i2cpParameters.getInbound_quantity(); |
||||
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); |
||||
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); |
||||
inbound_quantityLabel = new QLabel(gridLayoutWidget_2); |
||||
inbound_quantityLabel->setObjectName(QStringLiteral("inbound_quantityLabel")); |
||||
horizontalLayout_2->addWidget(inbound_quantityLabel); |
||||
inbound_quantityLineEdit = new QLineEdit(gridLayoutWidget_2); |
||||
inbound_quantityLineEdit->setObjectName(QStringLiteral("inbound_quantityLineEdit")); |
||||
inbound_quantityLineEdit->setText(inbound_quantity); |
||||
inbound_quantityLineEdit->setMaximumWidth(80); |
||||
QObject::connect(inbound_quantityLineEdit, SIGNAL(textChanged(const QString &)), |
||||
this, SLOT(updated())); |
||||
horizontalLayout_2->addWidget(inbound_quantityLineEdit); |
||||
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); |
||||
horizontalLayout_2->addItem(horizontalSpacer); |
||||
tunnelGridLayout->addLayout(horizontalLayout_2); |
||||
} |
||||
{ |
||||
//number of outbound tunnels
|
||||
const QString& outbound_quantity=i2cpParameters.getOutbound_quantity(); |
||||
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); |
||||
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); |
||||
outbound_quantityLabel = new QLabel(gridLayoutWidget_2); |
||||
outbound_quantityLabel->setObjectName(QStringLiteral("outbound_quantityLabel")); |
||||
horizontalLayout_2->addWidget(outbound_quantityLabel); |
||||
outbound_quantityLineEdit = new QLineEdit(gridLayoutWidget_2); |
||||
outbound_quantityLineEdit->setObjectName(QStringLiteral("outbound_quantityLineEdit")); |
||||
outbound_quantityLineEdit->setText(outbound_quantity); |
||||
outbound_quantityLineEdit->setMaximumWidth(80); |
||||
QObject::connect(outbound_quantityLineEdit, SIGNAL(textChanged(const QString &)), |
||||
this, SLOT(updated())); |
||||
horizontalLayout_2->addWidget(outbound_quantityLineEdit); |
||||
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); |
||||
horizontalLayout_2->addItem(horizontalSpacer); |
||||
tunnelGridLayout->addLayout(horizontalLayout_2); |
||||
} |
||||
{ |
||||
//number of ElGamal/AES tags to send
|
||||
const QString& crypto_tagsToSend=i2cpParameters.getCrypto_tagsToSend(); |
||||
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); |
||||
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); |
||||
crypto_tagsToSendLabel = new QLabel(gridLayoutWidget_2); |
||||
crypto_tagsToSendLabel->setObjectName(QStringLiteral("crypto_tagsToSendLabel")); |
||||
horizontalLayout_2->addWidget(crypto_tagsToSendLabel); |
||||
crypto_tagsToSendLineEdit = new QLineEdit(gridLayoutWidget_2); |
||||
crypto_tagsToSendLineEdit->setObjectName(QStringLiteral("crypto_tagsToSendLineEdit")); |
||||
crypto_tagsToSendLineEdit->setText(crypto_tagsToSend); |
||||
crypto_tagsToSendLineEdit->setMaximumWidth(80); |
||||
QObject::connect(crypto_tagsToSendLineEdit, SIGNAL(textChanged(const QString &)), |
||||
this, SLOT(updated())); |
||||
horizontalLayout_2->addWidget(crypto_tagsToSendLineEdit); |
||||
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); |
||||
horizontalLayout_2->addItem(horizontalSpacer); |
||||
tunnelGridLayout->addLayout(horizontalLayout_2); |
||||
} |
||||
|
||||
{ |
||||
//explicitPeers -- list of comma-separated b64 addresses of peers to use, default: unset
|
||||
const QString& value=i2cpParameters.getExplicitPeers(); |
||||
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); |
||||
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); |
||||
QLabel *_Label; |
||||
explicitPeersLabel = _Label = new QLabel(gridLayoutWidget_2); |
||||
_Label->setObjectName(QStringLiteral("_Label")); |
||||
horizontalLayout_2->addWidget(_Label); |
||||
QLineEdit *_LineEdit; |
||||
explicitPeersLineEdit = _LineEdit = new QLineEdit(gridLayoutWidget_2); |
||||
_LineEdit->setObjectName(QStringLiteral("_LineEdit")); |
||||
_LineEdit->setText(value); |
||||
_LineEdit->setMaximumWidth(80); |
||||
QObject::connect(_LineEdit, SIGNAL(textChanged(const QString &)), |
||||
this, SLOT(updated())); |
||||
horizontalLayout_2->addWidget(_LineEdit); |
||||
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); |
||||
horizontalLayout_2->addItem(horizontalSpacer); |
||||
tunnelGridLayout->addLayout(horizontalLayout_2); |
||||
} |
||||
|
||||
{ |
||||
//i2p.streaming.initialAckDelay -- milliseconds to wait before sending Ack. 200 by default
|
||||
const QString& value=i2cpParameters.get_i2p_streaming_initialAckDelay(); |
||||
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); |
||||
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); |
||||
QLabel *_Label; |
||||
i2p_streaming_initialAckDelayLabel = _Label = new QLabel(gridLayoutWidget_2); |
||||
_Label->setObjectName(QStringLiteral("_Label")); |
||||
horizontalLayout_2->addWidget(_Label); |
||||
QLineEdit *_LineEdit; |
||||
i2p_streaming_initialAckDelayLineEdit = _LineEdit = new QLineEdit(gridLayoutWidget_2); |
||||
_LineEdit->setObjectName(QStringLiteral("_LineEdit")); |
||||
_LineEdit->setText(value); |
||||
_LineEdit->setMaximumWidth(80); |
||||
QObject::connect(_LineEdit, SIGNAL(textChanged(const QString &)), |
||||
this, SLOT(updated())); |
||||
horizontalLayout_2->addWidget(_LineEdit); |
||||
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); |
||||
horizontalLayout_2->addItem(horizontalSpacer); |
||||
tunnelGridLayout->addLayout(horizontalLayout_2); |
||||
} |
||||
|
||||
{ |
||||
//i2p.streaming.answerPings -- enable sending pongs. true by default
|
||||
const bool value=i2cpParameters.get_i2p_streaming_answerPings(); |
||||
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); |
||||
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); |
||||
QCheckBox *_CheckBox; |
||||
i2p_streaming_answerPingsCheckBox = _CheckBox = new QCheckBox(gridLayoutWidget_2); |
||||
_CheckBox->setObjectName(QStringLiteral("_CheckBox")); |
||||
horizontalLayout_2->addWidget(_CheckBox); |
||||
_CheckBox->setChecked(value); |
||||
QObject::connect(_CheckBox, SIGNAL(toggled(bool)), |
||||
this, SLOT(updated())); |
||||
tunnelGridLayout->addLayout(horizontalLayout_2); |
||||
} |
||||
|
||||
{ |
||||
//i2cp.leaseSetType -- type of LeaseSet to be sent. 1, 3 or 5. 1 by default
|
||||
const QString& value=i2cpParameters.get_i2cp_leaseSetType(); |
||||
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); |
||||
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); |
||||
QLabel *_Label; |
||||
i2cp_leaseSetTypeLabel = _Label = new QLabel(gridLayoutWidget_2); |
||||
_Label->setObjectName(QStringLiteral("_Label")); |
||||
horizontalLayout_2->addWidget(_Label); |
||||
QLineEdit *_LineEdit; |
||||
i2cp_leaseSetTypeLineEdit = _LineEdit = new QLineEdit(gridLayoutWidget_2); |
||||
_LineEdit->setObjectName(QStringLiteral("_LineEdit")); |
||||
_LineEdit->setText(value); |
||||
_LineEdit->setMaximumWidth(80); |
||||
QObject::connect(_LineEdit, SIGNAL(textChanged(const QString &)), |
||||
this, SLOT(updated())); |
||||
horizontalLayout_2->addWidget(_LineEdit); |
||||
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); |
||||
horizontalLayout_2->addItem(horizontalSpacer); |
||||
tunnelGridLayout->addLayout(horizontalLayout_2); |
||||
} |
||||
|
||||
{ |
||||
//i2cp.leaseSetEncType -- comma separated encryption types to be used in LeaseSet type 3 or 5. Identity's type by default
|
||||
const QString& value=i2cpParameters.get_i2cp_leaseSetEncType(); |
||||
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); |
||||
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); |
||||
QLabel *_Label; |
||||
i2cp_leaseSetEncTypeLabel = _Label = new QLabel(gridLayoutWidget_2); |
||||
_Label->setObjectName(QStringLiteral("_Label")); |
||||
horizontalLayout_2->addWidget(_Label); |
||||
QLineEdit *_LineEdit; |
||||
i2cp_leaseSetEncTypeLineEdit = _LineEdit = new QLineEdit(gridLayoutWidget_2); |
||||
_LineEdit->setObjectName(QStringLiteral("_LineEdit")); |
||||
_LineEdit->setText(value); |
||||
_LineEdit->setMaximumWidth(80); |
||||
QObject::connect(_LineEdit, SIGNAL(textChanged(const QString &)), |
||||
this, SLOT(updated())); |
||||
horizontalLayout_2->addWidget(_LineEdit); |
||||
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); |
||||
horizontalLayout_2->addItem(horizontalSpacer); |
||||
tunnelGridLayout->addLayout(horizontalLayout_2); |
||||
} |
||||
|
||||
{ |
||||
//i2cp.leaseSetPrivKey -- decryption key for encrypted LeaseSet in base64. PSK or private DH
|
||||
const QString& value=i2cpParameters.get_i2cp_leaseSetPrivKey(); |
||||
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); |
||||
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); |
||||
QLabel *_Label; |
||||
i2cp_leaseSetPrivKeyLabel = _Label = new QLabel(gridLayoutWidget_2); |
||||
_Label->setObjectName(QStringLiteral("_Label")); |
||||
horizontalLayout_2->addWidget(_Label); |
||||
QLineEdit *_LineEdit; |
||||
i2cp_leaseSetPrivKeyLineEdit = _LineEdit = new QLineEdit(gridLayoutWidget_2); |
||||
_LineEdit->setObjectName(QStringLiteral("_LineEdit")); |
||||
_LineEdit->setText(value); |
||||
_LineEdit->setMaximumWidth(80); |
||||
QObject::connect(_LineEdit, SIGNAL(textChanged(const QString &)), |
||||
this, SLOT(updated())); |
||||
horizontalLayout_2->addWidget(_LineEdit); |
||||
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); |
||||
horizontalLayout_2->addItem(horizontalSpacer); |
||||
tunnelGridLayout->addLayout(horizontalLayout_2); |
||||
} |
||||
|
||||
{ |
||||
//i2cp.leaseSetAuthType -- authentication type for encrypted LeaseSet. 0 - no authentication(default), 1 - DH, 2 - PSK
|
||||
const QString& value=i2cpParameters.get_i2cp_leaseSetAuthType(); |
||||
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); |
||||
horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2")); |
||||
QLabel *_Label; |
||||
i2cp_leaseSetAuthTypeLabel = _Label = new QLabel(gridLayoutWidget_2); |
||||
_Label->setObjectName(QStringLiteral("_Label")); |
||||
horizontalLayout_2->addWidget(_Label); |
||||
QLineEdit *_LineEdit; |
||||
i2cp_leaseSetAuthTypeLineEdit = _LineEdit = new QLineEdit(gridLayoutWidget_2); |
||||
_LineEdit->setObjectName(QStringLiteral("_LineEdit")); |
||||
_LineEdit->setText(value); |
||||
_LineEdit->setMaximumWidth(80); |
||||
QObject::connect(_LineEdit, SIGNAL(textChanged(const QString &)), |
||||
this, SLOT(updated())); |
||||
horizontalLayout_2->addWidget(_LineEdit); |
||||
QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); |
||||
horizontalLayout_2->addItem(horizontalSpacer); |
||||
tunnelGridLayout->addLayout(horizontalLayout_2); |
||||
} |
||||
|
||||
retranslateI2CPParameters(); |
||||
} |
||||
|
||||
void TunnelPane::updated() { |
||||
std::string oldName=tunnelConfig->getName(); |
||||
//validate and show red if invalid
|
||||
hideWrongInputLabel(); |
||||
if(!mainWindow->applyTunnelsUiToConfigs())return; |
||||
tunnelsPageUpdateListener->updated(oldName, tunnelConfig); |
||||
} |
||||
|
||||
void TunnelPane::deleteButtonReleased() { |
||||
QMessageBox msgBox; |
||||
msgBox.setText(QApplication::tr("Are you sure to delete this tunnel?")); |
||||
msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); |
||||
msgBox.setDefaultButton(QMessageBox::Cancel); |
||||
int ret = msgBox.exec(); |
||||
switch (ret) { |
||||
case QMessageBox::Ok: |
||||
// OK was clicked
|
||||
hideWrongInputLabel(); |
||||
tunnelsPageUpdateListener->needsDeleting(tunnelConfig->getName()); |
||||
break; |
||||
case QMessageBox::Cancel: |
||||
// Cancel was clicked
|
||||
return; |
||||
} |
||||
} |
||||
|
||||
/*
|
||||
const char I2P_TUNNELS_SECTION_TYPE_CLIENT[] = "client"; |
||||
const char I2P_TUNNELS_SECTION_TYPE_SERVER[] = "server"; |
||||
const char I2P_TUNNELS_SECTION_TYPE_HTTP[] = "http"; |
||||
const char I2P_TUNNELS_SECTION_TYPE_IRC[] = "irc"; |
||||
const char I2P_TUNNELS_SECTION_TYPE_UDPCLIENT[] = "udpclient"; |
||||
const char I2P_TUNNELS_SECTION_TYPE_UDPSERVER[] = "udpserver"; |
||||
const char I2P_TUNNELS_SECTION_TYPE_SOCKS[] = "socks"; |
||||
const char I2P_TUNNELS_SECTION_TYPE_WEBSOCKS[] = "websocks"; |
||||
const char I2P_TUNNELS_SECTION_TYPE_HTTPPROXY[] = "httpproxy"; |
||||
*/ |
||||
QString TunnelPane::readTunnelTypeComboboxData() { |
||||
return tunnelTypeComboBox->currentData().toString(); |
||||
} |
||||
|
||||
i2p::data::SigningKeyType TunnelPane::readSigTypeComboboxUI(QComboBox* sigTypeComboBox) { |
||||
return (i2p::data::SigningKeyType) sigTypeComboBox->currentData().toInt(); |
||||
} |
||||
|
||||
void TunnelPane::deleteTunnelForm() { |
||||
widgetlocks.deleteListeners(); |
||||
} |
||||
|
||||
void TunnelPane::highlightWrongInput(QString warningText, QWidget* controlWithWrongInput) { |
||||
wrongInputPane->setVisible(true); |
||||
wrongInputLabel->setText(warningText); |
||||
mainWindow->adjustSizesAccordingToWrongLabel(); |
||||
if(controlWithWrongInput){ |
||||
mainWindow->ui->tunnelsScrollArea->ensureWidgetVisible(controlWithWrongInput); |
||||
controlWithWrongInput->setFocus(); |
||||
} |
||||
mainWindow->showTunnelsPage(); |
||||
} |
||||
|
||||
void TunnelPane::hideWrongInputLabel() const { |
||||
wrongInputPane->setVisible(false); |
||||
mainWindow->adjustSizesAccordingToWrongLabel(); |
||||
} |
||||
|
||||
bool TunnelPane::isValidSingleLine(QLineEdit* widget) { |
||||
return ::isValidSingleLine(widget, WrongInputPageEnum::tunnelsSettingsPage, mainWindow); |
||||
} |
@ -1,191 +0,0 @@
@@ -1,191 +0,0 @@
|
||||
#ifndef TUNNELPANE_H |
||||
#define TUNNELPANE_H |
||||
|
||||
#include "QObject" |
||||
#include "QWidget" |
||||
#include "QComboBox" |
||||
#include "QGridLayout" |
||||
#include "QLabel" |
||||
#include "QPushButton" |
||||
#include "QApplication" |
||||
#include "QLineEdit" |
||||
#include "QGroupBox" |
||||
#include "QVBoxLayout" |
||||
#include "QCheckBox" |
||||
|
||||
#include "TunnelConfig.h" |
||||
|
||||
#include <widgetlock.h> |
||||
#include <widgetlockregistry.h> |
||||
|
||||
class ServerTunnelPane; |
||||
class ClientTunnelPane; |
||||
|
||||
class TunnelConfig; |
||||
class I2CPParameters; |
||||
|
||||
class MainWindow; |
||||
|
||||
class TunnelPane : public QObject { |
||||
|
||||
Q_OBJECT |
||||
|
||||
public: |
||||
TunnelPane(TunnelsPageUpdateListener* tunnelsPageUpdateListener_, TunnelConfig* tunconf, QWidget* wrongInputPane_, QLabel* wrongInputLabel_, MainWindow* mainWindow_); |
||||
virtual ~TunnelPane(){} |
||||
|
||||
void deleteTunnelForm(); |
||||
|
||||
void hideWrongInputLabel() const; |
||||
void highlightWrongInput(QString warningText, QWidget* controlWithWrongInput); |
||||
|
||||
virtual ServerTunnelPane* asServerTunnelPane()=0; |
||||
virtual ClientTunnelPane* asClientTunnelPane()=0; |
||||
|
||||
void deleteWidget(); |
||||
|
||||
protected: |
||||
MainWindow* mainWindow; |
||||
QWidget * wrongInputPane; |
||||
QLabel* wrongInputLabel; |
||||
TunnelConfig* tunnelConfig; |
||||
widgetlockregistry widgetlocks; |
||||
TunnelsPageUpdateListener* tunnelsPageUpdateListener; |
||||
QVBoxLayout *tunnelGridLayout; |
||||
QGroupBox *tunnelGroupBox; |
||||
QWidget* gridLayoutWidget_2; |
||||
|
||||
//header
|
||||
QLabel *nameLabel; |
||||
QLineEdit *nameLineEdit; |
||||
public: |
||||
QLineEdit * getNameLineEdit() { return nameLineEdit; } |
||||
|
||||
public slots: |
||||
void updated(); |
||||
void deleteButtonReleased(); |
||||
|
||||
protected: |
||||
QSpacerItem *headerHorizontalSpacer; |
||||
QPushButton *deletePushButton; |
||||
|
||||
//type
|
||||
QComboBox *tunnelTypeComboBox; |
||||
QLabel *typeLabel; |
||||
|
||||
//i2cp
|
||||
|
||||
QLabel * inbound_lengthLabel; |
||||
QLineEdit * inbound_lengthLineEdit; |
||||
|
||||
QLabel * outbound_lengthLabel; |
||||
QLineEdit * outbound_lengthLineEdit; |
||||
|
||||
QLabel * inbound_quantityLabel; |
||||
QLineEdit * inbound_quantityLineEdit; |
||||
|
||||
QLabel * outbound_quantityLabel; |
||||
QLineEdit * outbound_quantityLineEdit; |
||||
|
||||
QLabel * crypto_tagsToSendLabel; |
||||
QLineEdit * crypto_tagsToSendLineEdit; |
||||
|
||||
QLabel * explicitPeersLabel; |
||||
QLineEdit * explicitPeersLineEdit; |
||||
|
||||
QLabel * i2p_streaming_initialAckDelayLabel; |
||||
QLineEdit * i2p_streaming_initialAckDelayLineEdit; |
||||
|
||||
QCheckBox * i2p_streaming_answerPingsCheckBox; |
||||
|
||||
QLabel * i2cp_leaseSetTypeLabel; |
||||
QLineEdit * i2cp_leaseSetTypeLineEdit; |
||||
|
||||
QLabel * i2cp_leaseSetEncTypeLabel; |
||||
QLineEdit * i2cp_leaseSetEncTypeLineEdit; |
||||
|
||||
QLabel * i2cp_leaseSetPrivKeyLabel; |
||||
QLineEdit * i2cp_leaseSetPrivKeyLineEdit; |
||||
|
||||
QLabel * i2cp_leaseSetAuthTypeLabel; |
||||
QLineEdit * i2cp_leaseSetAuthTypeLineEdit; |
||||
|
||||
|
||||
QString readTunnelTypeComboboxData(); |
||||
|
||||
//should be created by factory
|
||||
i2p::data::SigningKeyType readSigTypeComboboxUI(QComboBox* sigTypeComboBox); |
||||
|
||||
public: |
||||
//returns false when invalid data at UI
|
||||
virtual bool applyDataFromUIToTunnelConfig() { |
||||
if(!isValidSingleLine(nameLineEdit)){ |
||||
setGroupBoxTitle(QApplication::translate("tunPage", "invalid_tunnel_name")); |
||||
return false; |
||||
} |
||||
if(!isValidSingleLine(inbound_lengthLineEdit))return false; |
||||
if(!isValidSingleLine(inbound_quantityLineEdit))return false; |
||||
if(!isValidSingleLine(outbound_lengthLineEdit))return false; |
||||
if(!isValidSingleLine(outbound_quantityLineEdit))return false; |
||||
if(!isValidSingleLine(crypto_tagsToSendLineEdit))return false; |
||||
if(!isValidSingleLine(i2cp_leaseSetAuthTypeLineEdit))return false; |
||||
if(!isValidSingleLine(i2cp_leaseSetEncTypeLineEdit))return false; |
||||
if(!isValidSingleLine(i2cp_leaseSetPrivKeyLineEdit))return false; |
||||
if(!isValidSingleLine(i2cp_leaseSetTypeLineEdit))return false; |
||||
if(!isValidSingleLine(i2p_streaming_initialAckDelayLineEdit))return false; |
||||
setGroupBoxTitle(nameLineEdit->text()); |
||||
tunnelConfig->setName(nameLineEdit->text().toStdString()); |
||||
tunnelConfig->setType(readTunnelTypeComboboxData()); |
||||
I2CPParameters& i2cpParams=tunnelConfig->getI2cpParameters(); |
||||
i2cpParams.setInbound_length(inbound_lengthLineEdit->text()); |
||||
i2cpParams.setInbound_quantity(inbound_quantityLineEdit->text()); |
||||
i2cpParams.setOutbound_length(outbound_lengthLineEdit->text()); |
||||
i2cpParams.setOutbound_quantity(outbound_quantityLineEdit->text()); |
||||
i2cpParams.setCrypto_tagsToSend(crypto_tagsToSendLineEdit->text()); |
||||
i2cpParams.set_i2cp_leaseSetAuthType(i2cp_leaseSetAuthTypeLineEdit->text()); |
||||
i2cpParams.set_i2cp_leaseSetEncType(i2cp_leaseSetEncTypeLineEdit->text()); |
||||
i2cpParams.set_i2cp_leaseSetPrivKey(i2cp_leaseSetPrivKeyLineEdit->text()); |
||||
i2cpParams.set_i2cp_leaseSetType(i2cp_leaseSetTypeLineEdit->text()); |
||||
i2cpParams.set_i2p_streaming_answerPings(i2p_streaming_answerPingsCheckBox->isChecked()); |
||||
i2cpParams.set_i2p_streaming_initialAckDelay(i2p_streaming_initialAckDelayLineEdit->text()); |
||||
return true; |
||||
} |
||||
protected: |
||||
void setupTunnelPane( |
||||
TunnelConfig* tunnelConfig, |
||||
QGroupBox *tunnelGroupBox, |
||||
QWidget* gridLayoutWidget_2, QComboBox * tunnelTypeComboBox, |
||||
QWidget *tunnelsFormGridLayoutWidget, int tunnelsRow, int height, int h); |
||||
void appendControlsForI2CPParameters(I2CPParameters& i2cpParameters, int& gridIndex); |
||||
public: |
||||
int height() { |
||||
return gridLayoutWidget_2?gridLayoutWidget_2->height():0; |
||||
} |
||||
|
||||
protected slots: |
||||
virtual void setGroupBoxTitle(const QString & title)=0; |
||||
private: |
||||
void retranslateTunnelForm(TunnelPane& ui) { |
||||
ui.deletePushButton->setText(QApplication::translate("tunForm", "Delete Tunnel", 0)); |
||||
ui.nameLabel->setText(QApplication::translate("tunForm", "Tunnel name:", 0)); |
||||
} |
||||
|
||||
void retranslateI2CPParameters() { |
||||
inbound_lengthLabel->setText(QApplication::translate("tunForm", "Number of hops of an inbound tunnel:", 0));; |
||||
outbound_lengthLabel->setText(QApplication::translate("tunForm", "Number of hops of an outbound tunnel:", 0));; |
||||
inbound_quantityLabel->setText(QApplication::translate("tunForm", "Number of inbound tunnels:", 0));; |
||||
outbound_quantityLabel->setText(QApplication::translate("tunForm", "Number of outbound tunnels:", 0));; |
||||
crypto_tagsToSendLabel->setText(QApplication::translate("tunForm", "Number of ElGamal/AES tags to send:", 0));; |
||||
explicitPeersLabel->setText(QApplication::translate("tunForm", "List of comma-separated b64 addresses of peers to use:", 0));; |
||||
i2p_streaming_initialAckDelayLabel->setText(QApplication::translate("tunForm", "Milliseconds to wait before sending Ack:", 0)); |
||||
i2p_streaming_answerPingsCheckBox->setText(QApplication::translate("tunForm", "Enable sending pongs", 0)); |
||||
i2cp_leaseSetTypeLabel->setText(QApplication::translate("tunForm", "Type of LeaseSet to be sent. 1, 3 or 5:", 0)); |
||||
i2cp_leaseSetEncTypeLabel->setText(QApplication::translate("tunForm", "Comma-separ. encr. types to be used in LeaseSet type 3 or 5:", 0)); |
||||
i2cp_leaseSetPrivKeyLabel->setText(QApplication::translate("tunForm", "Decryption key for encrypted LeaseSet in base64. PSK or private DH:", 0)); |
||||
i2cp_leaseSetAuthTypeLabel->setText(QApplication::translate("tunForm", "Auth type for encrypted LeaseSet. 0 - no auth, 1 - DH, 2 - PSK:", 0)); |
||||
} |
||||
protected: |
||||
bool isValidSingleLine(QLineEdit* widget); |
||||
}; |
||||
|
||||
#endif // TUNNELPANE_H
|
@ -1,12 +0,0 @@
@@ -1,12 +0,0 @@
|
||||
#ifndef TUNNELSPAGEUPDATELISTENER_H |
||||
#define TUNNELSPAGEUPDATELISTENER_H |
||||
|
||||
class TunnelConfig; |
||||
|
||||
class TunnelsPageUpdateListener { |
||||
public: |
||||
virtual void updated(std::string oldName, TunnelConfig* tunConf)=0; |
||||
virtual void needsDeleting(std::string oldName)=0; |
||||
}; |
||||
|
||||
#endif // TUNNELSPAGEUPDATELISTENER_H
|
Before Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 53 KiB |
Before Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 4.8 KiB |
Before Width: | Height: | Size: 168 KiB |
Before Width: | Height: | Size: 7.1 KiB |
@ -1,57 +0,0 @@
@@ -1,57 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<!-- Copyright 2018 Viktor Villainov <supervillain@riseup.net> --> |
||||
<component type="desktop"> |
||||
<id>website.i2pd.i2pd</id> |
||||
<launchable type="desktop-id">website.i2pd.i2pd.desktop</launchable> |
||||
<metadata_license>CC0-1.0</metadata_license> |
||||
<project_license>BSD-3-Clause</project_license> |
||||
<name>i2pd</name> |
||||
<summary>Invisible Internet</summary> |
||||
<description> |
||||
<p>i2pd (I2P Daemon) is a full-featured C++ implementation of I2P client.</p> |
||||
<p>I2P (Invisible Internet Protocol) is a universal anonymous network layer. |
||||
All communications over I2P are anonymous and end-to-end encrypted, participants |
||||
don't reveal their real IP addresses. </p> |
||||
<p>I2P allows people from all around the world to communicate and share information |
||||
without restrictions.</p> |
||||
<p>Features:</p> |
||||
<ul> |
||||
<li>Distributed anonymous networking framework</li> |
||||
<li>End-to-end encrypted communications</li> |
||||
<li>Small footprint, simple dependencies, fast performance</li> |
||||
<li>Rich set of APIs for developers of secure applications</li> |
||||
</ul> |
||||
</description> |
||||
<screenshots> |
||||
<screenshot type="default"> |
||||
<image height="590" width="923">https://i2pd.website/images/i2pd_qt.png</image> |
||||
</screenshot> |
||||
</screenshots> |
||||
<url type="homepage">https://i2pd.website/</url> |
||||
<url type="bugtracker">https://github.com/PurpleI2P/i2pd/issues</url> |
||||
<url type="help">https://i2pd.readthedocs.io/en/latest/</url> |
||||
<update_contact>supervillain@riseup.net</update_contact> |
||||
<developer_name>PurpleI2P Team</developer_name> |
||||
<translation type="qt" /> |
||||
|
||||
<releases> |
||||
<release version="2.35.0" date="2020-11-30" /> |
||||
<release version="2.34.0" date="2020-10-27" /> |
||||
<release version="2.33.0" date="2020-08-24" /> |
||||
<release version="2.32.1" date="2020-06-02" /> |
||||
<release version="2.32.0" date="2020-05-25" /> |
||||
<release version="2.31.0" date="2020-04-10" /> |
||||
<release version="2.30.0" date="2020-02-25" /> |
||||
<release version="2.29.0" date="2019-10-21" /> |
||||
<release version="2.28.0" date="2019-08-27" /> |
||||
<release version="2.27.0" date="2019-07-03" /> |
||||
<release version="2.26.0" date="2019-06-07" /> |
||||
<release version="2.25.0" date="2019-05-09" /> |
||||
<release version="2.24.0" date="2019-03-21" /> |
||||
<release version="2.23.0" date="2019-01-21" /> |
||||
<release version="2.22.0" date="2018-11-09" /> |
||||
<release version="2.21.1" date="2018-10-22" /> |
||||
<release version="2.21.0" date="2018-10-04" /> |
||||
</releases> |
||||
<content_rating type="oars-1.1" /> |
||||
</component> |
@ -1,11 +0,0 @@
@@ -1,11 +0,0 @@
|
||||
[Desktop Entry] |
||||
Categories=Network;P2P;Qt; |
||||
Exec=i2pd_qt |
||||
GenericName=Invisible Internet |
||||
Comment=A universal anonymous network layer |
||||
Icon=website.i2pd.i2pd |
||||
Name=i2pd |
||||
Terminal=false |
||||
Type=Application |
||||
StartupNotify=false |
||||
Keywords=i2p;i2pd;vpn;p2p; |
@ -1,6 +0,0 @@
@@ -1,6 +0,0 @@
|
||||
<!DOCTYPE RCC><RCC version="1.0"> |
||||
<qresource prefix="/icons"> |
||||
<file alias="mask">resources/icons/mask.ico</file> |
||||
<file alias="icon">resources/images/icon.png</file> |
||||
</qresource> |
||||
</RCC> |
@ -1,32 +0,0 @@
@@ -1,32 +0,0 @@
|
||||
IDI_ICON1 ICON DISCARDABLE "resources/icons/mask.ico" |
||||
|
||||
#include <windows.h> // needed for VERSIONINFO |
||||
#include "../../libi2pd/version.h" |
||||
|
||||
VS_VERSION_INFO VERSIONINFO |
||||
FILEVERSION I2PD_VERSION_MAJOR,I2PD_VERSION_MINOR,I2PD_VERSION_MICRO,I2PD_VERSION_PATCH |
||||
PRODUCTVERSION I2P_VERSION_MAJOR,I2P_VERSION_MINOR,I2P_VERSION_MICRO,I2P_VERSION_PATCH |
||||
FILEOS VOS_NT_WINDOWS32 |
||||
FILETYPE VFT_APP |
||||
BEGIN |
||||
BLOCK "StringFileInfo" |
||||
BEGIN |
||||
BLOCK "040904E4" // U.S. English - multilingual (hex) |
||||
BEGIN |
||||
VALUE "CompanyName", "PurpleI2P" |
||||
VALUE "FileDescription", "I2Pd Qt" |
||||
VALUE "FileVersion", I2PD_VERSION |
||||
VALUE "InternalName", "i2pd-qt" |
||||
VALUE "LegalCopyright", "Copyright (C) 2013-2020, The PurpleI2P Project" |
||||
VALUE "LegalTrademarks1", "Distributed under the BSD 3-Clause software license, see the accompanying file COPYING or https://opensource.org/licenses/BSD-3-Clause." |
||||
VALUE "OriginalFilename", "i2pd_qt.exe" |
||||
VALUE "ProductName", "i2pd-qt" |
||||
VALUE "ProductVersion", I2P_VERSION |
||||
END |
||||
END |
||||
|
||||
BLOCK "VarFileInfo" |
||||
BEGIN |
||||
VALUE "Translation", 0x0, 1252 // language neutral - multilingual (decimal) |
||||
END |
||||
END |
@ -1,179 +0,0 @@
@@ -1,179 +0,0 @@
|
||||
QT += core gui |
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets |
||||
|
||||
TARGET = i2pd_qt |
||||
TEMPLATE = app |
||||
QMAKE_CXXFLAGS *= -Wno-unused-parameter -Wno-maybe-uninitialized -Wno-deprecated-copy |
||||
CONFIG += strict_c++ c++11 |
||||
|
||||
CONFIG(debug, debug|release) { |
||||
message(Debug build) |
||||
|
||||
# do not redirect logging to std::ostream and to Log pane |
||||
DEFINES += DEBUG_WITH_DEFAULT_LOGGING |
||||
|
||||
DEFINES += I2PD_QT_DEBUG |
||||
I2PDMAKE += DEBUG=yes |
||||
} else { |
||||
message(Release build) |
||||
DEFINES += I2PD_QT_RELEASE |
||||
I2PDMAKE += DEBUG=no |
||||
} |
||||
|
||||
SOURCES += DaemonQT.cpp mainwindow.cpp \ |
||||
ClientTunnelPane.cpp \ |
||||
MainWindowItems.cpp \ |
||||
ServerTunnelPane.cpp \ |
||||
SignatureTypeComboboxFactory.cpp \ |
||||
TunnelConfig.cpp \ |
||||
TunnelPane.cpp \ |
||||
textbrowsertweaked1.cpp \ |
||||
pagewithbackbutton.cpp \ |
||||
widgetlock.cpp \ |
||||
widgetlockregistry.cpp \ |
||||
logviewermanager.cpp \ |
||||
DelayedSaveManager.cpp \ |
||||
Saver.cpp \ |
||||
DelayedSaveManagerImpl.cpp \ |
||||
SaverImpl.cpp \ |
||||
../../daemon/Daemon.cpp \ |
||||
../../daemon/HTTPServer.cpp \ |
||||
../../daemon/I2PControl.cpp \ |
||||
../../daemon/i2pd.cpp \ |
||||
../../daemon/UPnP.cpp \ |
||||
AboutDialog.cpp \ |
||||
I2pdQtUtil.cpp |
||||
|
||||
HEADERS += DaemonQT.h mainwindow.h \ |
||||
ClientTunnelPane.h \ |
||||
MainWindowItems.h \ |
||||
ServerTunnelPane.h \ |
||||
SignatureTypeComboboxFactory.h \ |
||||
TunnelConfig.h \ |
||||
TunnelPane.h \ |
||||
TunnelsPageUpdateListener.h \ |
||||
textbrowsertweaked1.h \ |
||||
pagewithbackbutton.h \ |
||||
widgetlock.h \ |
||||
widgetlockregistry.h \ |
||||
i2pd.rc \ |
||||
logviewermanager.h \ |
||||
DelayedSaveManager.h \ |
||||
Saver.h \ |
||||
DelayedSaveManagerImpl.h \ |
||||
SaverImpl.h \ |
||||
../../daemon/Daemon.h \ |
||||
../../daemon/HTTPServer.h \ |
||||
../../daemon/I2PControl.h \ |
||||
../../daemon/UPnP.h \ |
||||
AboutDialog.h \ |
||||
BuildDateTimeQt.h \ |
||||
I2pdQtUtil.h \ |
||||
I2pdQtTypes.h |
||||
|
||||
INCLUDEPATH += ../../libi2pd |
||||
INCLUDEPATH += ../../libi2pd_client |
||||
INCLUDEPATH += ../../daemon |
||||
INCLUDEPATH += . |
||||
|
||||
FORMS += mainwindow.ui \ |
||||
tunnelform.ui \ |
||||
statusbuttons.ui \ |
||||
routercommandswidget.ui \ |
||||
generalsettingswidget.ui \ |
||||
AboutDialog.ui |
||||
|
||||
LIBS += $$PWD/../../libi2pd.a $$PWD/../../libi2pdclient.a -lz |
||||
|
||||
libi2pd.commands = @echo Building i2pd libraries |
||||
libi2pd.target = $$PWD/../../libi2pd.a |
||||
libi2pd.depends = i2pd FORCE |
||||
|
||||
i2pd.commands = cd $$PWD/../../ && mkdir -p obj/libi2pd obj/libi2pd_client && CC=$$QMAKE_CC CXX=$$QMAKE_CXX $(MAKE) USE_UPNP=yes $$I2PDMAKE mk_obj_dir api_client |
||||
i2pd.target += $$PWD/../../libi2pdclient.a |
||||
i2pd.depends = FORCE |
||||
|
||||
cleani2pd.commands = cd $$PWD/../../ && CC=$$QMAKE_CC CXX=$$QMAKE_CXX $(MAKE) clean |
||||
cleani2pd.depends = clean |
||||
|
||||
BuildDateTimeQtTarget.target = BuildDateTimeQt.h |
||||
BuildDateTimeQtTarget.depends = FORCE |
||||
# 'touch' is unix-only; will probably break on non-unix, TBD |
||||
BuildDateTimeQtTarget.commands = touch $$PWD/BuildDateTimeQt.h |
||||
PRE_TARGETDEPS += BuildDateTimeQt.h |
||||
QMAKE_EXTRA_TARGETS += BuildDateTimeQtTarget |
||||
|
||||
# git only, port to other VCS, too. TBD |
||||
DEFINES += VCS_COMMIT_INFO="\\\"git:$(shell git -C \""$$_PRO_FILE_PWD_"\" describe)\\\"" |
||||
|
||||
PRE_TARGETDEPS += $$PWD/../../libi2pd.a $$PWD/../../libi2pdclient.a |
||||
QMAKE_EXTRA_TARGETS += cleani2pd i2pd libi2pd |
||||
CLEAN_DEPS += cleani2pd |
||||
|
||||
|
||||
macx { |
||||
message("using mac os x target") |
||||
BREWROOT=/usr/local |
||||
BOOSTROOT=$$BREWROOT/opt/boost |
||||
SSLROOT=$$BREWROOT/opt/libressl |
||||
UPNPROOT=$$BREWROOT/opt/miniupnpc |
||||
INCLUDEPATH += $$BOOSTROOT/include |
||||
INCLUDEPATH += $$SSLROOT/include |
||||
INCLUDEPATH += $$UPNPROOT/include |
||||
LIBS += $$SSLROOT/lib/libcrypto.a |
||||
LIBS += $$SSLROOT/lib/libssl.a |
||||
LIBS += $$BOOSTROOT/lib/libboost_system.a |
||||
LIBS += $$BOOSTROOT/lib/libboost_date_time.a |
||||
LIBS += $$BOOSTROOT/lib/libboost_filesystem.a |
||||
LIBS += $$BOOSTROOT/lib/libboost_program_options.a |
||||
LIBS += $$UPNPROOT/lib/libminiupnpc.a |
||||
LIBS += -Wl,-dead_strip |
||||
LIBS += -Wl,-dead_strip_dylibs |
||||
LIBS += -Wl,-bind_at_load |
||||
} |
||||
|
||||
linux:!android { |
||||
message("Using Linux settings") |
||||
LIBS += -lcrypto -lssl -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread -lminiupnpc |
||||
} |
||||
|
||||
windows { |
||||
message("Using Windows settings") |
||||
RC_FILE = i2pd.rc |
||||
DEFINES += BOOST_USE_WINDOWS_H WINDOWS _WINDOWS WIN32_LEAN_AND_MEAN MINIUPNP_STATICLIB |
||||
DEFINES -= UNICODE _UNICODE |
||||
BOOST_SUFFIX = -mt |
||||
QMAKE_CXXFLAGS_RELEASE = -Os |
||||
QMAKE_LFLAGS = -Wl,-Bstatic -static-libgcc -static-libstdc++ -mwindows |
||||
|
||||
# linker's -s means "strip" |
||||
QMAKE_LFLAGS_RELEASE += -s |
||||
|
||||
LIBS = \ |
||||
$$PWD/../../libi2pd.a $$PWD/../../libi2pdclient.a \ |
||||
-lminiupnpc \ |
||||
-lboost_system$$BOOST_SUFFIX \ |
||||
-lboost_date_time$$BOOST_SUFFIX \ |
||||
-lboost_filesystem$$BOOST_SUFFIX \ |
||||
-lboost_program_options$$BOOST_SUFFIX \ |
||||
-lssl \ |
||||
-lcrypto \ |
||||
-lz \ |
||||
-lwsock32 \ |
||||
-lws2_32 \ |
||||
-lgdi32 \ |
||||
-liphlpapi \ |
||||
-lstdc++ \ |
||||
-lpthread |
||||
} |
||||
|
||||
!android:!symbian:!maemo5:!simulator { |
||||
message("Build with a system tray icon") |
||||
# see also http://doc.qt.io/qt-4.8/qt-desktop-systray-systray-pro.html for example on wince* |
||||
#sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS i2pd_qt.pro resources images |
||||
RESOURCES = i2pd.qrc |
||||
QT += xml |
||||
#INSTALLS += sources |
||||
} |
||||
|
@ -1,45 +0,0 @@
@@ -1,45 +0,0 @@
|
||||
#include "logviewermanager.h" |
||||
|
||||
LogViewerManager::LogViewerManager(std::shared_ptr<std::iostream> logStream_, |
||||
QPlainTextEdit* logTextEdit_, |
||||
QObject *parent) : |
||||
QObject(parent), |
||||
logStream(logStream_), |
||||
logTextEdit(logTextEdit_), |
||||
controllerForBgThread(nullptr) |
||||
{ |
||||
assert(logTextEdit!=nullptr); |
||||
controllerForBgThread=new i2pd::qt::logviewer::Controller(*this); |
||||
} |
||||
|
||||
namespace i2pd { |
||||
namespace qt { |
||||
namespace logviewer { |
||||
|
||||
QString Worker::pollAndShootATimerForInfiniteRetries() { |
||||
std::shared_ptr<std::iostream> logStream=logViewerManager.getLogStream(); |
||||
if(!logStream)return ""; |
||||
std::streamsize MAX_SZ=64*1024; |
||||
char*buf=(char*)malloc(MAX_SZ*sizeof(char)); |
||||
if(buf==nullptr)return ""; |
||||
std::streamsize read=logStream->readsome(buf, MAX_SZ); |
||||
if(read<0)read=0; |
||||
QString ret=QString::fromUtf8(buf, read); |
||||
free(buf); |
||||
return ret; |
||||
} |
||||
|
||||
Controller::Controller(LogViewerManager ¶meter1):logViewerManager(parameter1) { |
||||
Worker *worker = new Worker(parameter1); |
||||
worker->moveToThread(&workerThread); |
||||
connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater); |
||||
connect(this, &Controller::operate1, worker, &Worker::doWork1); |
||||
connect(worker, &Worker::resultReady, |
||||
¶meter1, &LogViewerManager::appendPlainText_atGuiThread); |
||||
workerThread.start(); |
||||
timerId=startTimer(100/*millis*/); |
||||
} |
||||
|
||||
} |
||||
} |
||||
} |
@ -1,130 +0,0 @@
@@ -1,130 +0,0 @@
|
||||
#ifndef LOGVIEWERMANAGER_H |
||||
#define LOGVIEWERMANAGER_H |
||||
|
||||
#include <QObject> |
||||
#include <QString> |
||||
#include <QPlainTextEdit> |
||||
#include <QScrollBar> |
||||
#include <QComboBox> |
||||
#include <QTimer> |
||||
#include <QThread> |
||||
|
||||
#include <assert.h> |
||||
#include <string> |
||||
|
||||
#include "FS.h" |
||||
#include "Log.h" |
||||
|
||||
class LogViewerManager; |
||||
|
||||
namespace i2pd { |
||||
namespace qt { |
||||
namespace logviewer { |
||||
|
||||
class Worker : public QObject |
||||
{ |
||||
Q_OBJECT |
||||
private: |
||||
LogViewerManager &logViewerManager; |
||||
public: |
||||
Worker(LogViewerManager ¶meter1):logViewerManager(parameter1){} |
||||
private: |
||||
QString pollAndShootATimerForInfiniteRetries(); |
||||
|
||||
public slots: |
||||
void doWork1() { |
||||
/* ... here is the expensive or blocking operation ... */ |
||||
QString read=pollAndShootATimerForInfiniteRetries(); |
||||
emit resultReady(read); |
||||
} |
||||
|
||||
signals: |
||||
void resultReady(QString read); |
||||
}; |
||||
|
||||
class Controller : public QObject |
||||
{ |
||||
Q_OBJECT |
||||
QThread workerThread; |
||||
LogViewerManager& logViewerManager; |
||||
int timerId; |
||||
public: |
||||
Controller(LogViewerManager ¶meter1); |
||||
~Controller() { |
||||
if(timerId!=0)killTimer(timerId); |
||||
workerThread.quit(); |
||||
workerThread.wait(); |
||||
} |
||||
signals: |
||||
void operate1(); |
||||
protected: |
||||
void timerEvent(QTimerEvent */*event*/) { |
||||
emit operate1(); |
||||
} |
||||
}; |
||||
|
||||
} |
||||
} |
||||
} |
||||
|
||||
class LogViewerManager : public QObject |
||||
{ |
||||
Q_OBJECT |
||||
private: |
||||
std::shared_ptr<std::iostream> logStream; |
||||
QPlainTextEdit* logTextEdit; |
||||
i2pd::qt::logviewer::Controller* controllerForBgThread; |
||||
public: |
||||
//also starts a bg thread (QTimer) polling logStream->readsome(buf, n)
|
||||
explicit LogViewerManager(std::shared_ptr<std::iostream> logStream_, |
||||
QPlainTextEdit* logTextEdit_, |
||||
QObject *parent); |
||||
//also deallocs the bg thread (QTimer)
|
||||
virtual ~LogViewerManager(){} |
||||
const i2pd::qt::logviewer::Controller& getControllerForBgThread() { |
||||
assert(controllerForBgThread!=nullptr); |
||||
return *controllerForBgThread; |
||||
} |
||||
const QPlainTextEdit* getLogTextEdit(){ return logTextEdit; } |
||||
const std::shared_ptr<std::iostream> getLogStream(){ return logStream; } |
||||
signals: |
||||
|
||||
public slots: |
||||
//void appendFromNonGuiThread(std::string read) {
|
||||
//}
|
||||
public slots: |
||||
void appendPlainText_atGuiThread(QString plainText) { |
||||
if(plainText.length()==0)return; |
||||
assert(logTextEdit!=nullptr); |
||||
int scrollPosVert =logTextEdit->verticalScrollBar()->value(); |
||||
int scrollPosHoriz=logTextEdit->horizontalScrollBar()->value(); |
||||
int scrollPosVertMax =logTextEdit->verticalScrollBar()->maximum(); |
||||
const int MAX_LINES=10*1024; |
||||
logTextEdit->setMaximumBlockCount(MAX_LINES); |
||||
//logTextEdit->appendPlainText(plainText);
|
||||
//navigate the window to the end
|
||||
//QTextCursor cursor = logTextEdit->textCursor();
|
||||
//cursor.movePosition(QTextCursor::MoveOperation::End);
|
||||
//logTextEdit->setTextCursor(cursor);
|
||||
//QTextCursor prev_cursor = logTextEdit->textCursor();
|
||||
logTextEdit->moveCursor(QTextCursor::End); |
||||
logTextEdit->insertPlainText(plainText); |
||||
if(/*prev_cursor.atEnd()*/scrollPosVert==scrollPosVertMax){ |
||||
//logTextEdit->moveCursor(QTextCursor::End);
|
||||
scrollPosVert =logTextEdit->verticalScrollBar()->maximum(); |
||||
scrollPosHoriz=logTextEdit->horizontalScrollBar()->minimum(); |
||||
} |
||||
//else
|
||||
// logTextEdit->setTextCursor(prev_cursor);
|
||||
logTextEdit->verticalScrollBar()->setValue(scrollPosVert); |
||||
logTextEdit->horizontalScrollBar()->setValue(scrollPosHoriz); |
||||
} |
||||
/*
|
||||
void replaceText_atGuiThread() { |
||||
assert(logTextEdit!=nullptr); |
||||
logTextEdit->setText(QString::fromStdString(nav.getContent())); |
||||
} |
||||
*/ |
||||
}; |
||||
|
||||
#endif // LOGVIEWERMANAGER_H
|
@ -1,883 +0,0 @@
@@ -1,883 +0,0 @@
|
||||
#ifndef MAINWINDOW_H |
||||
#define MAINWINDOW_H |
||||
|
||||
#include <QObject> |
||||
#include <QMainWindow> |
||||
#include <QPushButton> |
||||
#include <QtCore/QVariant> |
||||
#include <QtWidgets/QAction> |
||||
#include <QtWidgets/QApplication> |
||||
#include <QtWidgets/QButtonGroup> |
||||
#include <QtWidgets/QHeaderView> |
||||
#include <QtWidgets/QMainWindow> |
||||
#include <QtWidgets/QVBoxLayout> |
||||
#include <QtWidgets/QWidget> |
||||
#include <QtWidgets/QCheckBox> |
||||
#include <QtWidgets/QComboBox> |
||||
#include <QtWidgets/QAction> |
||||
#include <QtWidgets/QGridLayout> |
||||
#include <QtWidgets/QGroupBox> |
||||
#include <QtWidgets/QHBoxLayout> |
||||
#include <QtWidgets/QHeaderView> |
||||
#include <QtWidgets/QLabel> |
||||
#include <QtWidgets/QLineEdit> |
||||
#include <QtWidgets/QPushButton> |
||||
#include <QtWidgets/QSpacerItem> |
||||
#include "QVBoxLayout" |
||||
#include "QUrl" |
||||
|
||||
#ifndef ANDROID |
||||
# include <QSystemTrayIcon> |
||||
# include <QCloseEvent> |
||||
# include <QMenu> |
||||
#endif |
||||
|
||||
#include <QString> |
||||
|
||||
#include <functional> |
||||
|
||||
#include "MainWindowItems.h" |
||||
#include "TunnelPane.h" |
||||
#include "ServerTunnelPane.h" |
||||
#include "ClientTunnelPane.h" |
||||
#include "TunnelConfig.h" |
||||
#include "textbrowsertweaked1.h" |
||||
|
||||
#include "Config.h" |
||||
#include "FS.h" |
||||
|
||||
#include <QDebug> |
||||
|
||||
#include <boost/property_tree/ptree.hpp> |
||||
#include <boost/property_tree/ini_parser.hpp> |
||||
|
||||
#include "TunnelsPageUpdateListener.h" |
||||
|
||||
#include "DaemonQT.h" |
||||
#include "SignatureTypeComboboxFactory.h" |
||||
#include "pagewithbackbutton.h" |
||||
|
||||
#include <iostream> |
||||
|
||||
#include "widgetlockregistry.h" |
||||
#include "widgetlock.h" |
||||
|
||||
#include "DelayedSaveManager.h" |
||||
#include "DelayedSaveManagerImpl.h" |
||||
#include "SaverImpl.h" |
||||
|
||||
#include "I2pdQtUtil.h" |
||||
|
||||
class SaverImpl; |
||||
|
||||
class LogViewerManager; |
||||
|
||||
template<typename ValueType> |
||||
bool isType(boost::any& a) { |
||||
return |
||||
#ifdef BOOST_AUX_ANY_TYPE_ID_NAME |
||||
std::strcmp(a.type().name(), typeid(ValueType).name()) == 0 |
||||
#else |
||||
a.type() == typeid(ValueType) |
||||
#endif |
||||
; |
||||
} |
||||
|
||||
class ConfigOption { |
||||
public: |
||||
QString section; |
||||
QString option; |
||||
//MainWindow::DefaultValueGetter defaultValueGetter;
|
||||
ConfigOption(QString section_, QString option_/*, DefaultValueGetter defaultValueGetter_*/): |
||||
section(section_) |
||||
, option(option_) |
||||
//, defaultValueGetter(defaultValueGetter_)
|
||||
{} |
||||
|
||||
}; |
||||
|
||||
extern std::string programOptionsWriterCurrentSection; |
||||
|
||||
class MainWindow; |
||||
|
||||
class MainWindowItem : public QObject { |
||||
Q_OBJECT |
||||
private: |
||||
ConfigOption option; |
||||
QWidget* widgetToFocus; |
||||
QString requirementToBeValid; |
||||
const bool readOnly; |
||||
public: |
||||
MainWindowItem(ConfigOption option_, QWidget* widgetToFocus_, QString requirementToBeValid_, bool readOnly_=false) : |
||||
option(option_), widgetToFocus(widgetToFocus_), requirementToBeValid(requirementToBeValid_), readOnly(readOnly_) {} |
||||
QWidget* getWidgetToFocus(){return widgetToFocus;} |
||||
QString& getRequirementToBeValid() { return requirementToBeValid; } |
||||
ConfigOption& getConfigOption() { return option; } |
||||
boost::any optionValue; |
||||
virtual ~MainWindowItem(){} |
||||
virtual void installListeners(MainWindow *mainWindow); |
||||
virtual void loadFromConfigOption(){ |
||||
std::string optName=""; |
||||
if(!option.section.isEmpty())optName=option.section.toStdString()+std::string("."); |
||||
optName+=option.option.toStdString(); |
||||
//qDebug() << "loadFromConfigOption[" << optName.c_str() << "]";
|
||||
boost::any programOption; |
||||
i2p::config::GetOptionAsAny(optName, programOption); |
||||
optionValue=programOption.empty()?boost::any(std::string("")) |
||||
:boost::any_cast<boost::program_options::variable_value>(programOption).value(); |
||||
} |
||||
virtual void saveToStringStream(std::stringstream& out){ |
||||
if(readOnly)return; //should readOnly items (conf=) error somewhere, instead of silently skipping save?
|
||||
if(isType<std::string>(optionValue)) { |
||||
std::string v = boost::any_cast<std::string>(optionValue); |
||||
if(v.empty())return; |
||||
} |
||||
if(optionValue.empty())return; |
||||
std::string rtti = optionValue.type().name(); |
||||
std::string optName=""; |
||||
if(!option.section.isEmpty())optName=option.section.toStdString()+std::string("."); |
||||
optName+=option.option.toStdString(); |
||||
//qDebug() << "Writing option" << optName.c_str() << "of type" << rtti.c_str();
|
||||
std::string sectionAsStdStr = option.section.toStdString(); |
||||
if(!option.section.isEmpty() && |
||||
sectionAsStdStr!=programOptionsWriterCurrentSection) { |
||||
out << "[" << sectionAsStdStr << "]\n"; |
||||
programOptionsWriterCurrentSection=sectionAsStdStr; |
||||
} |
||||
out << option.option.toStdString() << "="; |
||||
if(isType<std::string>(optionValue)) { |
||||
out << boost::any_cast<std::string>(optionValue); |
||||
}else if(isType<bool>(optionValue)) { |
||||
out << (boost::any_cast<bool>(optionValue) ? "true" : "false"); |
||||
}else if(isType<uint16_t>(optionValue)) { |
||||
out << boost::any_cast<uint16_t>(optionValue); |
||||
}else if(isType<uint32_t>(optionValue)) { |
||||
out << boost::any_cast<uint32_t>(optionValue); |
||||
}else if(isType<int>(optionValue)) { |
||||
out << boost::any_cast<int>(optionValue); |
||||
}else if(isType<unsigned short>(optionValue)) { |
||||
out << boost::any_cast<unsigned short>(optionValue); |
||||
}else out << boost::any_cast<std::string>(optionValue); //let it throw
|
||||
out << "\n\n"; |
||||
} |
||||
virtual bool isValid(bool & alreadyDisplayedIfWrong){alreadyDisplayedIfWrong=false;return true;} |
||||
}; |
||||
class NonGUIOptionItem : public MainWindowItem { |
||||
public: |
||||
NonGUIOptionItem(ConfigOption option_) : MainWindowItem(option_, nullptr, QString()) {} |
||||
virtual ~NonGUIOptionItem(){} |
||||
//virtual bool isValid(bool & alreadyDisplayedIfWrong) { return true; }
|
||||
}; |
||||
class BaseStringItem : public MainWindowItem { |
||||
Q_OBJECT |
||||
public: |
||||
QLineEdit* lineEdit; |
||||
MainWindow *mainWindow; |
||||
BaseStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString requirementToBeValid_, MainWindow* mainWindow_, bool readOnly=false): |
||||
MainWindowItem(option_, lineEdit_, requirementToBeValid_, readOnly), |
||||
lineEdit(lineEdit_), |
||||
mainWindow(mainWindow_) |
||||
{}; |
||||
virtual ~BaseStringItem(){} |
||||
virtual void installListeners(MainWindow *mainWindow); |
||||
virtual QString toString(){ |
||||
return boost::any_cast<std::string>(optionValue).c_str(); |
||||
} |
||||
virtual boost::any fromString(QString s){return boost::any(s.toStdString());} |
||||
virtual void loadFromConfigOption(){ |
||||
MainWindowItem::loadFromConfigOption(); |
||||
lineEdit->setText(toString()); |
||||
} |
||||
|
||||
virtual void saveToStringStream(std::stringstream& out){ |
||||
optionValue=fromString(lineEdit->text()); |
||||
MainWindowItem::saveToStringStream(out); |
||||
} |
||||
virtual bool isValid(bool & alreadyDisplayedIfWrong); |
||||
}; |
||||
class FileOrFolderChooserItem : public BaseStringItem { |
||||
protected: |
||||
const bool requireExistingFile; |
||||
public: |
||||
QPushButton* browsePushButton; |
||||
FileOrFolderChooserItem(ConfigOption option_, QLineEdit* lineEdit_, QPushButton* browsePushButton_, MainWindow* mw, bool requireExistingFile_, bool readOnly) : |
||||
BaseStringItem(option_, lineEdit_, QString(), mw, readOnly), requireExistingFile(requireExistingFile_), browsePushButton(browsePushButton_) {} |
||||
virtual ~FileOrFolderChooserItem(){} |
||||
}; |
||||
class FileChooserItem : public FileOrFolderChooserItem { |
||||
Q_OBJECT |
||||
private slots: |
||||
void pushButtonReleased(); |
||||
public: |
||||
FileChooserItem(ConfigOption option_, QLineEdit* lineEdit_, QPushButton* browsePushButton_, MainWindow* mw, bool requireExistingFile, bool readOnly) : |
||||
FileOrFolderChooserItem(option_, lineEdit_, browsePushButton_, mw, requireExistingFile, readOnly) { |
||||
QObject::connect(browsePushButton, SIGNAL(released()), this, SLOT(pushButtonReleased())); |
||||
} |
||||
}; |
||||
class FolderChooserItem : public FileOrFolderChooserItem{ |
||||
Q_OBJECT |
||||
private slots: |
||||
void pushButtonReleased(); |
||||
public: |
||||
FolderChooserItem(ConfigOption option_, QLineEdit* lineEdit_, QPushButton* browsePushButton_, MainWindow* mw, bool requireExistingFolder) : |
||||
FileOrFolderChooserItem(option_, lineEdit_, browsePushButton_, mw, requireExistingFolder, false) { |
||||
QObject::connect(browsePushButton, SIGNAL(released()), this, SLOT(pushButtonReleased())); |
||||
} |
||||
}; |
||||
class ComboBoxItem : public MainWindowItem { |
||||
public: |
||||
QComboBox* comboBox; |
||||
ComboBoxItem(ConfigOption option_, QComboBox* comboBox_) : MainWindowItem(option_,comboBox_,QString()), comboBox(comboBox_){} |
||||
virtual ~ComboBoxItem(){} |
||||
virtual void installListeners(MainWindow *mainWindow); |
||||
virtual void loadFromConfigOption()=0; |
||||
virtual void saveToStringStream(std::stringstream& out)=0; |
||||
//virtual bool isValid(bool & alreadyDisplayedIfWrong) { return ; }
|
||||
}; |
||||
class LogDestinationComboBoxItem : public ComboBoxItem { |
||||
public: |
||||
LogDestinationComboBoxItem(ConfigOption option_, QComboBox* comboBox_) : |
||||
ComboBoxItem(option_, comboBox_) {} |
||||
virtual ~LogDestinationComboBoxItem(){} |
||||
virtual void loadFromConfigOption(){ |
||||
MainWindowItem::loadFromConfigOption(); |
||||
const char * ld = boost::any_cast<std::string>(optionValue).c_str(); |
||||
comboBox->setCurrentText(QString(ld)); |
||||
} |
||||
virtual void saveToStringStream(std::stringstream& out){ |
||||
std::string logDest = comboBox->currentText().toStdString(); |
||||
optionValue=logDest; |
||||
MainWindowItem::saveToStringStream(out); |
||||
} |
||||
//virtual bool isValid(bool & alreadyDisplayedIfWrong) { return true; }
|
||||
|
||||
Q_OBJECT |
||||
}; |
||||
class LogLevelComboBoxItem : public ComboBoxItem { |
||||
public: |
||||
LogLevelComboBoxItem(ConfigOption option_, QComboBox* comboBox_) : ComboBoxItem(option_, comboBox_) {} |
||||
virtual ~LogLevelComboBoxItem(){} |
||||
virtual void loadFromConfigOption(){ |
||||
MainWindowItem::loadFromConfigOption(); |
||||
const char * ll = boost::any_cast<std::string>(optionValue).c_str(); |
||||
comboBox->setCurrentText(QString(ll)); |
||||
} |
||||
virtual void saveToStringStream(std::stringstream& out){ |
||||
optionValue=comboBox->currentText().toStdString(); |
||||
MainWindowItem::saveToStringStream(out); |
||||
} |
||||
//virtual bool isValid(bool & alreadyDisplayedIfWrong) { return true; }
|
||||
}; |
||||
class SignatureTypeComboBoxItem : public ComboBoxItem { |
||||
public: |
||||
SignatureTypeComboBoxItem(ConfigOption option_, QComboBox* comboBox_) : ComboBoxItem(option_, comboBox_) {} |
||||
virtual ~SignatureTypeComboBoxItem(){} |
||||
virtual void loadFromConfigOption(){ |
||||
MainWindowItem::loadFromConfigOption(); |
||||
while(comboBox->count()>0)comboBox->removeItem(0); |
||||
uint16_t selected = (uint16_t) boost::any_cast<unsigned short>(optionValue); |
||||
SignatureTypeComboBoxFactory::fillComboBox(comboBox, selected); |
||||
} |
||||
virtual void saveToStringStream(std::stringstream& out){ |
||||
uint16_t selected = SignatureTypeComboBoxFactory::getSigType(comboBox->currentData()); |
||||
optionValue=(unsigned short)selected; |
||||
MainWindowItem::saveToStringStream(out); |
||||
} |
||||
//virtual bool isValid(bool & alreadyDisplayedIfWrong) { return true; }
|
||||
}; |
||||
class CheckBoxItem : public MainWindowItem { |
||||
public: |
||||
QCheckBox* checkBox; |
||||
CheckBoxItem(ConfigOption option_, QCheckBox* checkBox_) : MainWindowItem(option_,checkBox_,QString()), checkBox(checkBox_){} |
||||
virtual ~CheckBoxItem(){} |
||||
virtual void installListeners(MainWindow *mainWindow); |
||||
virtual void loadFromConfigOption(){ |
||||
MainWindowItem::loadFromConfigOption(); |
||||
//qDebug() << "setting value for checkbox " << checkBox->text();
|
||||
checkBox->setChecked(boost::any_cast<bool>(optionValue)); |
||||
} |
||||
virtual void saveToStringStream(std::stringstream& out){ |
||||
optionValue=checkBox->isChecked(); |
||||
MainWindowItem::saveToStringStream(out); |
||||
} |
||||
//virtual bool isValid(bool & alreadyDisplayedIfWrong) { return true; }
|
||||
}; |
||||
class BaseFormattedStringItem : public BaseStringItem { |
||||
public: |
||||
QString fieldNameTranslated; |
||||
BaseFormattedStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_, QString requirementToBeValid_, MainWindow* mw) : |
||||
BaseStringItem(option_, lineEdit_, requirementToBeValid_, mw), fieldNameTranslated(fieldNameTranslated_) {} |
||||
virtual ~BaseFormattedStringItem(){} |
||||
//virtual bool isValid(bool & alreadyDisplayedIfWrong)=0;
|
||||
}; |
||||
class IntegerStringItem : public BaseFormattedStringItem { |
||||
public: |
||||
IntegerStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_, MainWindow* mw) : |
||||
BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_, QApplication::tr("Must be a valid integer."), mw) {} |
||||
virtual ~IntegerStringItem(){} |
||||
virtual bool isValid(bool & alreadyDisplayedIfWrong){ |
||||
bool correct = BaseFormattedStringItem::isValid(alreadyDisplayedIfWrong); |
||||
if(!correct)return false; |
||||
alreadyDisplayedIfWrong = false; |
||||
auto str=lineEdit->text(); |
||||
bool ok; |
||||
str.toInt(&ok); |
||||
return ok; |
||||
} |
||||
virtual QString toString(){return QString::number(boost::any_cast<int>(optionValue));} |
||||
virtual boost::any fromString(QString s){return boost::any(std::stoi(s.toStdString()));} |
||||
}; |
||||
class UShortStringItem : public BaseFormattedStringItem { |
||||
public: |
||||
UShortStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_, MainWindow* mw) : |
||||
BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_, QApplication::tr("Must be unsigned short integer."), mw) {} |
||||
virtual ~UShortStringItem(){} |
||||
virtual bool isValid(bool & alreadyDisplayedIfWrong){ |
||||
bool correct = BaseFormattedStringItem::isValid(alreadyDisplayedIfWrong); |
||||
if(!correct)return false; |
||||
alreadyDisplayedIfWrong = false; |
||||
auto str=lineEdit->text(); |
||||
bool ok; |
||||
str.toUShort(&ok); |
||||
return ok; |
||||
} |
||||
virtual QString toString(){return QString::number(boost::any_cast<unsigned short>(optionValue));} |
||||
virtual boost::any fromString(QString s){return boost::any((unsigned short)std::stoi(s.toStdString()));} |
||||
}; |
||||
class UInt32StringItem : public BaseFormattedStringItem { |
||||
public: |
||||
UInt32StringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_, MainWindow* mw) : |
||||
BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_, QApplication::tr("Must be unsigned 32-bit integer."), mw) {} |
||||
virtual ~UInt32StringItem(){} |
||||
virtual bool isValid(bool & alreadyDisplayedIfWrong){ |
||||
bool correct = BaseFormattedStringItem::isValid(alreadyDisplayedIfWrong); |
||||
if(!correct)return false; |
||||
alreadyDisplayedIfWrong = false; |
||||
auto str=lineEdit->text(); |
||||
bool ok; |
||||
str.toUInt(&ok); |
||||
return ok; |
||||
} |
||||
virtual QString toString(){return QString::number(boost::any_cast<uint32_t>(optionValue));} |
||||
virtual boost::any fromString(QString s){return boost::any((uint32_t)std::stoi(s.toStdString()));} |
||||
}; |
||||
class UInt16StringItem : public BaseFormattedStringItem { |
||||
public: |
||||
UInt16StringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_, MainWindow* mw) : |
||||
BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_, QApplication::tr("Must be unsigned 16-bit integer."), mw) {} |
||||
virtual ~UInt16StringItem(){} |
||||
virtual bool isValid(bool & alreadyDisplayedIfWrong){ |
||||
bool correct = BaseFormattedStringItem::isValid(alreadyDisplayedIfWrong); |
||||
if(!correct)return false; |
||||
alreadyDisplayedIfWrong = false; |
||||
auto str=lineEdit->text(); |
||||
bool ok; |
||||
str.toUShort(&ok); |
||||
return ok; |
||||
} |
||||
virtual QString toString(){return QString::number(boost::any_cast<uint16_t>(optionValue));} |
||||
virtual boost::any fromString(QString s){return boost::any((uint16_t)std::stoi(s.toStdString()));} |
||||
}; |
||||
class IPAddressStringItem : public BaseFormattedStringItem { |
||||
public: |
||||
IPAddressStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_, MainWindow* mw) : |
||||
BaseFormattedStringItem(option_, lineEdit_, fieldNameTranslated_, QApplication::tr("Must be an IPv4 address"), mw) {} |
||||
//virtual bool isValid(bool & alreadyDisplayedIfWrong){return true;}//todo
|
||||
}; |
||||
class TCPPortStringItem : public UShortStringItem { |
||||
public: |
||||
TCPPortStringItem(ConfigOption option_, QLineEdit* lineEdit_, QString fieldNameTranslated_, MainWindow* mw) : |
||||
UShortStringItem(option_, lineEdit_, fieldNameTranslated_,mw) {} |
||||
}; |
||||
|
||||
namespace Ui { |
||||
class MainWindow; |
||||
class StatusButtonsForm; |
||||
class routerCommandsWidget; |
||||
class GeneralSettingsContentsForm; |
||||
} |
||||
|
||||
using namespace i2p::client; |
||||
|
||||
class TunnelPane; |
||||
|
||||
using namespace i2p::qt; |
||||
|
||||
class Controller; |
||||
|
||||
class DelayedSaveManagerImpl; |
||||
|
||||
class MainWindow : public QMainWindow { |
||||
Q_OBJECT |
||||
private: |
||||
std::string currentLocalDestinationB32; |
||||
std::shared_ptr<std::iostream> logStream; |
||||
DelayedSaveManagerImpl* delayedSaveManagerPtr; |
||||
DelayedSaveManager::DATA_SERIAL_TYPE dataSerial; |
||||
public: |
||||
explicit MainWindow(std::shared_ptr<std::iostream> logStream_, QWidget *parent=nullptr); |
||||
~MainWindow(); |
||||
|
||||
void setI2PController(i2p::qt::Controller* controller_); |
||||
|
||||
void highlightWrongInput(QString warningText, WrongInputPageEnum inputPage, QWidget* widgetToFocus); |
||||
|
||||
//typedef std::function<QString ()> DefaultValueGetter;
|
||||
|
||||
//#ifndef ANDROID
|
||||
// void setVisible(bool visible);
|
||||
//#endif
|
||||
|
||||
private: |
||||
enum StatusPage {main_page, commands, local_destinations, leasesets, tunnels, transit_tunnels, |
||||
transports, i2p_tunnels, sam_sessions}; |
||||
private slots: |
||||
void updated(); |
||||
|
||||
void handleQuitButton(); |
||||
void handleGracefulQuitButton(); |
||||
void handleDoRestartButton(); |
||||
void handleGracefulQuitTimerEvent(); |
||||
#ifndef ANDROID |
||||
void setIcon(); |
||||
void iconActivated(QSystemTrayIcon::ActivationReason reason); |
||||
void toggleVisibilitySlot(); |
||||
#endif |
||||
void scheduleStatusPageUpdates(); |
||||
void statusHtmlPageMouseReleased(); |
||||
void statusHtmlPageSelectionChanged(); |
||||
void updateStatusPage(); |
||||
|
||||
void showStatusMainPage(); |
||||
void showStatus_commands_Page(); |
||||
void runPeerTest(); |
||||
void enableTransit(); |
||||
void disableTransit(); |
||||
|
||||
public slots: |
||||
void syncLogLevel (int comboBoxIndex); |
||||
|
||||
void showStatus_local_destinations_Page(); |
||||
void showStatus_leasesets_Page(); |
||||
void showStatus_tunnels_Page(); |
||||
void showStatus_transit_tunnels_Page(); |
||||
void showStatus_transports_Page(); |
||||
void showStatus_i2p_tunnels_Page(); |
||||
void showStatus_sam_sessions_Page(); |
||||
|
||||
void showLogViewerPage(); |
||||
void showSettingsPage(); |
||||
void showTunnelsPage(); |
||||
void showRestartPage(); |
||||
void showQuitPage(); |
||||
void showAboutBox(const QString & href); |
||||
|
||||
private: |
||||
StatusPage statusPage; |
||||
QTimer * statusPageUpdateTimer; |
||||
bool wasSelectingAtStatusMainPage; |
||||
bool showHiddenInfoStatusMainPage; |
||||
|
||||
LogViewerManager *logViewerManagerPtr; |
||||
|
||||
void showStatusPage(StatusPage newStatusPage); |
||||
#ifndef ANDROID |
||||
void createActions(); |
||||
void createTrayIcon(); |
||||
bool quitting; |
||||
QAction *toggleWindowVisibleAction; |
||||
QSystemTrayIcon *trayIcon; |
||||
QMenu *trayIconMenu; |
||||
#endif |
||||
|
||||
public: |
||||
Ui::MainWindow* ui; |
||||
Ui::StatusButtonsForm* statusButtonsUI; |
||||
Ui::routerCommandsWidget* routerCommandsUI; |
||||
Ui::GeneralSettingsContentsForm* uiSettings; |
||||
void adjustSizesAccordingToWrongLabel(); |
||||
bool applyTunnelsUiToConfigs(); |
||||
private: |
||||
int settingsTitleLabelNominalHeight; |
||||
TextBrowserTweaked1 * textBrowser; |
||||
QWidget * routerCommandsParent; |
||||
PageWithBackButton * pageWithBackButton; |
||||
TextBrowserTweaked1 * childTextBrowser; |
||||
|
||||
widgetlockregistry widgetlocks; |
||||
|
||||
i2p::qt::Controller* i2pController; |
||||
|
||||
protected: |
||||
|
||||
void updateRouterCommandsButtons(); |
||||
|
||||
#ifndef ANDROID |
||||
void closeEvent(QCloseEvent *event); |
||||
#endif |
||||
void resizeEvent(QResizeEvent* event); |
||||
void onResize(); |
||||
|
||||
void setStatusButtonsVisible(bool visible); |
||||
|
||||
QString getStatusPageHtml(bool showHiddenInfo); |
||||
|
||||
QList<MainWindowItem*> configItems; |
||||
NonGUIOptionItem* daemonOption; |
||||
NonGUIOptionItem* serviceOption; |
||||
//LogDestinationComboBoxItem* logOption;
|
||||
FileChooserItem* logFileNameOption; |
||||
|
||||
FileChooserItem* initFileChooser(ConfigOption option, QLineEdit* fileNameLineEdit, QPushButton* fileBrowsePushButton, bool requireExistingFile, bool readOnly=false); |
||||
void initFolderChooser(ConfigOption option, QLineEdit* folderLineEdit, QPushButton* folderBrowsePushButton); |
||||
//void initCombobox(ConfigOption option, QComboBox* comboBox);
|
||||
void initLogDestinationCombobox(ConfigOption option, QComboBox* comboBox); |
||||
void initLogLevelCombobox(ConfigOption option, QComboBox* comboBox); |
||||
void initSignatureTypeCombobox(ConfigOption option, QComboBox* comboBox); |
||||
void initIPAddressBox(ConfigOption option, QLineEdit* addressLineEdit, QString fieldNameTranslated); |
||||
void initTCPPortBox(ConfigOption option, QLineEdit* portLineEdit, QString fieldNameTranslated); |
||||
void initCheckBox(ConfigOption option, QCheckBox* checkBox); |
||||
void initIntegerBox(ConfigOption option, QLineEdit* numberLineEdit, QString fieldNameTranslated); |
||||
void initUInt32Box(ConfigOption option, QLineEdit* numberLineEdit, QString fieldNameTranslated); |
||||
void initUInt16Box(ConfigOption option, QLineEdit* numberLineEdit, QString fieldNameTranslated); |
||||
void initStringBox(ConfigOption option, QLineEdit* lineEdit); |
||||
NonGUIOptionItem* initNonGUIOption(ConfigOption option); |
||||
|
||||
void loadAllConfigs(SaverImpl* saverPtr); |
||||
void layoutTunnels(); |
||||
|
||||
public slots: |
||||
/** returns false iff not valid items present and save was aborted */ |
||||
bool saveAllConfigs(bool reloadAfterSave, FocusEnum focusOn, std::string tunnelNameToFocus="", QWidget* widgetToFocus=nullptr); |
||||
void reloadTunnelsConfigAndUI(std::string tunnelNameToFocus, QWidget* widgetToFocus); |
||||
void reloadTunnelsConfigAndUI() { reloadTunnelsConfigAndUI("", nullptr); } |
||||
|
||||
//focus none
|
||||
void reloadTunnelsConfigAndUI_QString(QString tunnelNameToFocus); |
||||
void addServerTunnelPushButtonReleased(); |
||||
void addClientTunnelPushButtonReleased(); |
||||
|
||||
void anchorClickedHandler(const QUrl & link); |
||||
void backClickedFromChild(); |
||||
|
||||
void logDestinationComboBoxValueChanged(const QString & text); |
||||
|
||||
private: |
||||
QString datadir; |
||||
QString confpath; |
||||
QString tunconfpath; |
||||
|
||||
std::map<std::string, TunnelConfig*> tunnelConfigs; |
||||
std::list<TunnelPane*> tunnelPanes; |
||||
|
||||
void appendTunnelForms(std::string tunnelNameToFocus); |
||||
void deleteTunnelForms(); |
||||
void deleteTunnelFromUI(std::string tunnelName, TunnelConfig* cnf); |
||||
|
||||
template<typename Section> |
||||
std::string GetI2CPOption (const Section& section, const std::string& name, const std::string& value) const |
||||
{ |
||||
return section.second.get (boost::property_tree::ptree::path_type (name, '/'), value); |
||||
} |
||||
|
||||
template<typename Section> |
||||
std::string GetI2CPOption (const Section& section, const std::string& name, const char* value) const |
||||
{ |
||||
return section.second.get (boost::property_tree::ptree::path_type (name, '/'), std::string (value)); |
||||
} |
||||
|
||||
template<typename Section, typename Type> |
||||
std::string GetI2CPOption (const Section& section, const std::string& name, const Type& value) const |
||||
{ |
||||
return section.second.get (boost::property_tree::ptree::path_type (name, '/'), std::to_string (value)); |
||||
} |
||||
|
||||
template<typename Section> |
||||
void ReadI2CPOptions (const Section& section, std::map<std::string, std::string>& options, I2CPParameters& param |
||||
/*TODO fill param*/) const |
||||
{ |
||||
std::string _INBOUND_TUNNEL_LENGTH = options[I2CP_PARAM_INBOUND_TUNNEL_LENGTH] = GetI2CPOption (section, I2CP_PARAM_INBOUND_TUNNEL_LENGTH, DEFAULT_INBOUND_TUNNEL_LENGTH); |
||||
param.setInbound_length(QString(_INBOUND_TUNNEL_LENGTH.c_str())); |
||||
std::string _OUTBOUND_TUNNEL_LENGTH = options[I2CP_PARAM_OUTBOUND_TUNNEL_LENGTH] = GetI2CPOption (section, I2CP_PARAM_OUTBOUND_TUNNEL_LENGTH, DEFAULT_OUTBOUND_TUNNEL_LENGTH); |
||||
param.setOutbound_length(QString(_OUTBOUND_TUNNEL_LENGTH.c_str())); |
||||
std::string _INBOUND_TUNNELS_QUANTITY = options[I2CP_PARAM_INBOUND_TUNNELS_QUANTITY] = GetI2CPOption (section, I2CP_PARAM_INBOUND_TUNNELS_QUANTITY, DEFAULT_INBOUND_TUNNELS_QUANTITY); |
||||
param.setInbound_quantity( QString(_INBOUND_TUNNELS_QUANTITY.c_str())); |
||||
std::string _OUTBOUND_TUNNELS_QUANTITY = options[I2CP_PARAM_OUTBOUND_TUNNELS_QUANTITY] = GetI2CPOption (section, I2CP_PARAM_OUTBOUND_TUNNELS_QUANTITY, DEFAULT_OUTBOUND_TUNNELS_QUANTITY); |
||||
param.setOutbound_quantity(QString(_OUTBOUND_TUNNELS_QUANTITY.c_str())); |
||||
std::string _TAGS_TO_SEND = options[I2CP_PARAM_TAGS_TO_SEND] = GetI2CPOption (section, I2CP_PARAM_TAGS_TO_SEND, DEFAULT_TAGS_TO_SEND); |
||||
param.setCrypto_tagsToSend(QString(_TAGS_TO_SEND.c_str())); |
||||
std::string _i2cp_leaseSetAuthType = options[I2CP_PARAM_LEASESET_AUTH_TYPE] = GetI2CPOption (section, I2CP_PARAM_LEASESET_AUTH_TYPE, 0); |
||||
param.set_i2cp_leaseSetAuthType(QString(_i2cp_leaseSetAuthType.c_str())); |
||||
const char DEFAULT_LEASESET_ENCRYPTION_TYPE[] = ""; |
||||
std::string _i2cp_leaseSetEncType = options[I2CP_PARAM_LEASESET_ENCRYPTION_TYPE] = GetI2CPOption (section, I2CP_PARAM_LEASESET_ENCRYPTION_TYPE, DEFAULT_LEASESET_ENCRYPTION_TYPE);//todo Identity's type by default
|
||||
param.set_i2cp_leaseSetEncType(QString(_i2cp_leaseSetEncType.c_str())); |
||||
std::string _i2cp_leaseSetPrivKey = options[I2CP_PARAM_LEASESET_PRIV_KEY] = GetI2CPOption (section, I2CP_PARAM_LEASESET_PRIV_KEY, ""); |
||||
param.set_i2cp_leaseSetPrivKey(QString(_i2cp_leaseSetPrivKey.c_str())); |
||||
std::string _i2cp_leaseSetType = options[I2CP_PARAM_LEASESET_TYPE] = GetI2CPOption (section, I2CP_PARAM_LEASESET_TYPE, DEFAULT_LEASESET_TYPE); |
||||
param.set_i2cp_leaseSetType(QString(_i2cp_leaseSetType.c_str())); |
||||
std::string _i2p_streaming_answerPings= options[I2CP_PARAM_STREAMING_ANSWER_PINGS] = GetI2CPOption (section, I2CP_PARAM_STREAMING_ANSWER_PINGS, DEFAULT_ANSWER_PINGS); |
||||
param.set_i2p_streaming_answerPings((_i2p_streaming_answerPings.compare("true")==0)||(_i2p_streaming_answerPings.compare("yes")==0)); |
||||
std::string _i2p_streaming_initialAckDelay = options[I2CP_PARAM_STREAMING_INITIAL_ACK_DELAY] = GetI2CPOption (section, I2CP_PARAM_STREAMING_INITIAL_ACK_DELAY, DEFAULT_INITIAL_ACK_DELAY); |
||||
param.set_i2p_streaming_initialAckDelay(QString(_i2p_streaming_initialAckDelay.c_str())); |
||||
options[I2CP_PARAM_MIN_TUNNEL_LATENCY] = GetI2CPOption(section, I2CP_PARAM_MIN_TUNNEL_LATENCY, DEFAULT_MIN_TUNNEL_LATENCY);//TODO include into param
|
||||
options[I2CP_PARAM_MAX_TUNNEL_LATENCY] = GetI2CPOption(section, I2CP_PARAM_MAX_TUNNEL_LATENCY, DEFAULT_MAX_TUNNEL_LATENCY);//TODO include into param
|
||||
} |
||||
|
||||
void CreateDefaultI2CPOptions (I2CPParameters& param |
||||
/*TODO fill param*/) const |
||||
{ |
||||
const int _INBOUND_TUNNEL_LENGTH = DEFAULT_INBOUND_TUNNEL_LENGTH; |
||||
param.setInbound_length(QString::number(_INBOUND_TUNNEL_LENGTH)); |
||||
const int _OUTBOUND_TUNNEL_LENGTH = DEFAULT_OUTBOUND_TUNNEL_LENGTH; |
||||
param.setOutbound_length(QString::number(_OUTBOUND_TUNNEL_LENGTH)); |
||||
const int _INBOUND_TUNNELS_QUANTITY = DEFAULT_INBOUND_TUNNELS_QUANTITY; |
||||
param.setInbound_quantity( QString::number(_INBOUND_TUNNELS_QUANTITY)); |
||||
const int _OUTBOUND_TUNNELS_QUANTITY = DEFAULT_OUTBOUND_TUNNELS_QUANTITY; |
||||
param.setOutbound_quantity(QString::number(_OUTBOUND_TUNNELS_QUANTITY)); |
||||
const int _TAGS_TO_SEND = DEFAULT_TAGS_TO_SEND; |
||||
param.setCrypto_tagsToSend(QString::number(_TAGS_TO_SEND)); |
||||
const int _i2cp_leaseSetAuthType = 0; |
||||
param.set_i2cp_leaseSetAuthType(QString::number(_i2cp_leaseSetAuthType)); |
||||
const QString _i2cp_leaseSetEncType = "0,4"; //todo Identity's type by default
|
||||
param.set_i2cp_leaseSetEncType(_i2cp_leaseSetEncType); |
||||
param.set_i2cp_leaseSetPrivKey(""); |
||||
const int _i2cp_leaseSetType = DEFAULT_LEASESET_TYPE; |
||||
param.set_i2cp_leaseSetType(QString::number(_i2cp_leaseSetType)); |
||||
bool _i2p_streaming_answerPings= DEFAULT_ANSWER_PINGS; |
||||
param.set_i2p_streaming_answerPings(_i2p_streaming_answerPings); |
||||
const int _i2p_streaming_initialAckDelay = DEFAULT_INITIAL_ACK_DELAY; |
||||
param.set_i2p_streaming_initialAckDelay(QString::number(_i2p_streaming_initialAckDelay)); |
||||
} |
||||
|
||||
|
||||
void DeleteTunnelNamed(std::string name) { |
||||
std::map<std::string,TunnelConfig*>::const_iterator it=tunnelConfigs.find(name); |
||||
if(it!=tunnelConfigs.end()){ |
||||
TunnelConfig* tc=it->second; |
||||
deleteTunnelFromUI(name, tc); |
||||
tunnelConfigs.erase(it); |
||||
delete tc; |
||||
} |
||||
saveAllConfigs(true, FocusEnum::noFocus); |
||||
} |
||||
|
||||
std::string GenerateNewTunnelName() { |
||||
int i=1; |
||||
while(true){ |
||||
std::stringstream name; |
||||
name << "name" << i; |
||||
const std::string& str=name.str(); |
||||
if(tunnelConfigs.find(str)==tunnelConfigs.end())return str; |
||||
++i; |
||||
} |
||||
} |
||||
|
||||
void CreateDefaultClientTunnel() {//TODO dedup default values with ReadTunnelsConfig() and with ClientContext.cpp::ReadTunnels ()
|
||||
std::string name=GenerateNewTunnelName(); |
||||
std::string type = I2P_TUNNELS_SECTION_TYPE_CLIENT; |
||||
std::string dest = "127.0.0.1"; |
||||
int port = 0; |
||||
std::string keys = ""; |
||||
std::string address = "127.0.0.1"; |
||||
int destinationPort = 0; |
||||
int cryptoType = 0; |
||||
i2p::data::SigningKeyType sigType = i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256; |
||||
// I2CP
|
||||
I2CPParameters i2cpParameters; |
||||
CreateDefaultI2CPOptions (i2cpParameters); |
||||
|
||||
tunnelConfigs[name]=new ClientTunnelConfig(name, QString(type.c_str()), i2cpParameters, |
||||
dest, |
||||
port, |
||||
keys, |
||||
address, |
||||
destinationPort, |
||||
sigType, |
||||
cryptoType); |
||||
|
||||
saveAllConfigs(true, FocusEnum::focusOnTunnelName, name); |
||||
} |
||||
|
||||
void CreateDefaultServerTunnel() {//TODO dedup default values with ReadTunnelsConfig() and with ClientContext.cpp::ReadTunnels ()
|
||||
std::string name=GenerateNewTunnelName(); |
||||
std::string type=I2P_TUNNELS_SECTION_TYPE_SERVER; |
||||
std::string host = "127.0.0.1"; |
||||
int port = 0; |
||||
std::string keys = ""; |
||||
int inPort = 0; |
||||
std::string accessList = ""; |
||||
std::string hostOverride = ""; |
||||
std::string webircpass = ""; |
||||
bool gzip = true; |
||||
i2p::data::SigningKeyType sigType = i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256; |
||||
std::string address = "127.0.0.1"; |
||||
bool isUniqueLocal = true; |
||||
int cryptoType = 0; |
||||
|
||||
// I2CP
|
||||
I2CPParameters i2cpParameters; |
||||
CreateDefaultI2CPOptions (i2cpParameters); |
||||
|
||||
tunnelConfigs[name]=new ServerTunnelConfig(name, QString(type.c_str()), i2cpParameters, |
||||
host, |
||||
port, |
||||
keys, |
||||
inPort, |
||||
accessList, |
||||
hostOverride, |
||||
webircpass, |
||||
gzip, |
||||
sigType, |
||||
address, |
||||
isUniqueLocal, |
||||
cryptoType); |
||||
|
||||
|
||||
saveAllConfigs(true, FocusEnum::focusOnTunnelName, name); |
||||
} |
||||
|
||||
void ReadTunnelsConfig() //TODO deduplicate the code with ClientContext.cpp::ReadTunnels ()
|
||||
{ |
||||
boost::property_tree::ptree pt; |
||||
std::string tunConf=tunconfpath.toStdString(); |
||||
if (tunConf == "") { |
||||
// TODO: cleanup this in 2.8.0
|
||||
tunConf = i2p::fs::DataDirPath ("tunnels.cfg"); |
||||
if (i2p::fs::Exists(tunConf)) { |
||||
LogPrint(eLogWarning, "FS: please rename tunnels.cfg -> tunnels.conf here: ", tunConf); |
||||
} else { |
||||
tunConf = i2p::fs::DataDirPath ("tunnels.conf"); |
||||
} |
||||
} |
||||
LogPrint(eLogDebug, "tunnels config file: ", tunConf); |
||||
try |
||||
{ |
||||
boost::property_tree::read_ini (tunConf, pt); |
||||
} |
||||
catch (std::exception& ex) |
||||
{ |
||||
LogPrint (eLogWarning, "Clients: Can't read ", tunConf, ": ", ex.what ());//TODO show err box and disable tunn.page
|
||||
return; |
||||
} |
||||
|
||||
for (auto& section: pt) |
||||
{ |
||||
std::string name = section.first; |
||||
try |
||||
{ |
||||
std::string type = section.second.get<std::string> (I2P_TUNNELS_SECTION_TYPE); |
||||
if (type == I2P_TUNNELS_SECTION_TYPE_CLIENT |
||||
|| type == I2P_TUNNELS_SECTION_TYPE_SOCKS |
||||
|| type == I2P_TUNNELS_SECTION_TYPE_WEBSOCKS |
||||
|| type == I2P_TUNNELS_SECTION_TYPE_HTTPPROXY |
||||
|| type == I2P_TUNNELS_SECTION_TYPE_UDPCLIENT) |
||||
{ |
||||
// mandatory params
|
||||
std::string dest; |
||||
if (type == I2P_TUNNELS_SECTION_TYPE_CLIENT || type == I2P_TUNNELS_SECTION_TYPE_UDPCLIENT) { |
||||
dest = section.second.get<std::string> (I2P_CLIENT_TUNNEL_DESTINATION); |
||||
} |
||||
int port = section.second.get<int> (I2P_CLIENT_TUNNEL_PORT); |
||||
// optional params
|
||||
std::string keys = section.second.get (I2P_CLIENT_TUNNEL_KEYS, ""); |
||||
std::string address = section.second.get (I2P_CLIENT_TUNNEL_ADDRESS, "127.0.0.1"); |
||||
int cryptoType = section.second.get<int>(I2P_CLIENT_TUNNEL_CRYPTO_TYPE, 0); |
||||
int destinationPort = section.second.get<int>(I2P_CLIENT_TUNNEL_DESTINATION_PORT, 0); |
||||
i2p::data::SigningKeyType sigType = section.second.get (I2P_CLIENT_TUNNEL_SIGNATURE_TYPE, i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256); |
||||
// I2CP
|
||||
std::map<std::string, std::string> options; |
||||
I2CPParameters i2cpParameters; |
||||
ReadI2CPOptions (section, options, i2cpParameters); |
||||
|
||||
tunnelConfigs[name]=new ClientTunnelConfig(name, QString(type.c_str()), i2cpParameters, |
||||
dest, |
||||
port, |
||||
keys, |
||||
address, |
||||
destinationPort, |
||||
sigType, |
||||
cryptoType); |
||||
} |
||||
else if (type == I2P_TUNNELS_SECTION_TYPE_SERVER |
||||
|| type == I2P_TUNNELS_SECTION_TYPE_HTTP |
||||
|| type == I2P_TUNNELS_SECTION_TYPE_IRC |
||||
|| type == I2P_TUNNELS_SECTION_TYPE_UDPSERVER) |
||||
{ |
||||
// mandatory params
|
||||
std::string host = section.second.get<std::string> (I2P_SERVER_TUNNEL_HOST); |
||||
int port = section.second.get<int> (I2P_SERVER_TUNNEL_PORT); |
||||
// optional params
|
||||
std::string keys = section.second.get<std::string> (I2P_SERVER_TUNNEL_KEYS, ""); |
||||
int inPort = section.second.get (I2P_SERVER_TUNNEL_INPORT, 0); |
||||
std::string accessList = section.second.get (I2P_SERVER_TUNNEL_ACCESS_LIST, ""); |
||||
std::string hostOverride = section.second.get (I2P_SERVER_TUNNEL_HOST_OVERRIDE, ""); |
||||
std::string webircpass = section.second.get<std::string> (I2P_SERVER_TUNNEL_WEBIRC_PASSWORD, ""); |
||||
bool gzip = section.second.get (I2P_SERVER_TUNNEL_GZIP, true); |
||||
i2p::data::SigningKeyType sigType = section.second.get (I2P_SERVER_TUNNEL_SIGNATURE_TYPE, i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256); |
||||
std::string address = section.second.get<std::string> (I2P_SERVER_TUNNEL_ADDRESS, "127.0.0.1"); |
||||
bool isUniqueLocal = section.second.get(I2P_SERVER_TUNNEL_ENABLE_UNIQUE_LOCAL, true); |
||||
int cryptoType = section.second.get<int>(I2P_CLIENT_TUNNEL_CRYPTO_TYPE, 0); |
||||
|
||||
// I2CP
|
||||
std::map<std::string, std::string> options; |
||||
I2CPParameters i2cpParameters; |
||||
ReadI2CPOptions (section, options, i2cpParameters); |
||||
|
||||
/*
|
||||
std::set<i2p::data::IdentHash> idents; |
||||
if (accessList.length () > 0) |
||||
{ |
||||
size_t pos = 0, comma; |
||||
do |
||||
{ |
||||
comma = accessList.find (',', pos); |
||||
i2p::data::IdentHash ident; |
||||
ident.FromBase32 (accessList.substr (pos, comma != std::string::npos ? comma - pos : std::string::npos)); |
||||
idents.insert (ident); |
||||
pos = comma + 1; |
||||
} |
||||
while (comma != std::string::npos); |
||||
} |
||||
*/ |
||||
tunnelConfigs[name]=new ServerTunnelConfig(name, QString(type.c_str()), i2cpParameters, |
||||
host, |
||||
port, |
||||
keys, |
||||
inPort, |
||||
accessList, |
||||
hostOverride, |
||||
webircpass, |
||||
gzip, |
||||
sigType, |
||||
address, |
||||
isUniqueLocal, |
||||
cryptoType); |
||||
} |
||||
else |
||||
LogPrint (eLogWarning, "Clients: Unknown section type=", type, " of ", name, " in ", tunConf);//TODO show err box and disable the tunn gui
|
||||
|
||||
} |
||||
catch (std::exception& ex) |
||||
{ |
||||
LogPrint (eLogError, "Clients: Can't read tunnel ", name, " params: ", ex.what ());//TODO show err box and disable the tunn gui
|
||||
} |
||||
} |
||||
} |
||||
|
||||
private: |
||||
class TunnelsPageUpdateListenerMainWindowImpl : public TunnelsPageUpdateListener { |
||||
MainWindow* mainWindow; |
||||
public: |
||||
TunnelsPageUpdateListenerMainWindowImpl(MainWindow* mainWindow_):mainWindow(mainWindow_){} |
||||
virtual void updated(std::string oldName, TunnelConfig* tunConf); |
||||
virtual void needsDeleting(std::string oldName); |
||||
}; |
||||
|
||||
TunnelsPageUpdateListenerMainWindowImpl tunnelsPageUpdateListener; |
||||
|
||||
//void onLoggingOptionsChange() {}
|
||||
|
||||
SaverImpl* saverPtr; |
||||
}; |
||||
|
||||
#endif // MAINWINDOW_H
|
@ -1,24 +0,0 @@
@@ -1,24 +0,0 @@
|
||||
#include "pagewithbackbutton.h" |
||||
#include "QVBoxLayout" |
||||
#include "QHBoxLayout" |
||||
#include "QPushButton" |
||||
|
||||
PageWithBackButton::PageWithBackButton(QWidget *parent, QWidget* child) : QWidget(parent) |
||||
{ |
||||
QVBoxLayout * layout = new QVBoxLayout(); |
||||
setLayout(layout); |
||||
QWidget * topBar = new QWidget(); |
||||
QHBoxLayout * topBarLayout = new QHBoxLayout(); |
||||
topBar->setLayout(topBarLayout); |
||||
layout->addWidget(topBar); |
||||
layout->addWidget(child); |
||||
|
||||
QPushButton * backButton = new QPushButton(topBar); |
||||
backButton->setText("< Back"); |
||||
topBarLayout->addWidget(backButton); |
||||
connect(backButton, SIGNAL(released()), this, SLOT(backReleasedSlot())); |
||||
} |
||||
|
||||
void PageWithBackButton::backReleasedSlot() { |
||||
emit backReleased(); |
||||
} |
@ -1,21 +0,0 @@
@@ -1,21 +0,0 @@
|
||||
#ifndef PAGEWITHBACKBUTTON_H |
||||
#define PAGEWITHBACKBUTTON_H |
||||
|
||||
#include <QWidget> |
||||
|
||||
class PageWithBackButton : public QWidget |
||||
{ |
||||
Q_OBJECT |
||||
public: |
||||
explicit PageWithBackButton(QWidget *parent, QWidget* child); |
||||
|
||||
signals: |
||||
|
||||
void backReleased(); |
||||
|
||||
private slots: |
||||
|
||||
void backReleasedSlot(); |
||||
}; |
||||
|
||||
#endif // PAGEWITHBACKBUTTON_H
|
Before Width: | Height: | Size: 153 KiB |
Before Width: | Height: | Size: 8.5 KiB |