implemented server side RC4 decoding and re-encoding, injecting, ..

This commit is contained in:
sirjonasxx 2018-04-04 02:28:24 +02:00
parent 43b864eb37
commit c27adf8a3d
51 changed files with 3296 additions and 384 deletions

View File

@ -0,0 +1,20 @@
<component name="ArtifactManager">
<artifact type="javafx" build-on-make="true" name="G-Earth2">
<output-path>$PROJECT_DIR$/out/artifacts/G_Earth</output-path>
<properties id="javafx-properties">
<options>
<option name="appClass" value="main.Main" />
<option name="description" value="" />
<option name="htmlPlaceholderId" value="" />
<option name="title" value="G-Earth" />
<option name="vendor" value="" />
<option name="version" value="" />
</options>
</properties>
<root id="root">
<element id="archive" name="G_Earth.jar">
<element id="module-output" name="G-Earth2" />
</element>
</root>
</artifact>
</component>

6
.idea/misc.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

8
.idea/modules.xml Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/G-Earth2.iml" filepath="$PROJECT_DIR$/G-Earth2.iml" />
</modules>
</component>
</project>

6
.idea/vcs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

1248
.idea/workspace.xml Normal file

File diff suppressed because it is too large Load Diff

11
G-Earth2.iml Normal file
View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@ -0,0 +1,43 @@
<html><head>
<SCRIPT src="http://java.com/js/dtjava.js"></SCRIPT>
<script>
function launchApplication(jnlpfile) {
dtjava.launch( {
url : 'G_Earth.jnlp'
},
{
javafx : '8.0+'
},
{}
);
return false;
}
</script>
<script>
function javafxEmbedG_Earth_id() {
dtjava.embed(
{
id : 'G_Earth_id',
url : 'G_Earth.jnlp',
placeholder : 'javafx-app-placeholder',
width : '600',
height : '400'
},
{
javafx : '8.0+'
},
{}
);
}
<!-- Embed FX application into web page once page is loaded -->
dtjava.addOnloadCallback(javafxEmbedG_Earth_id);
</script>
</head><body>
<h2>Test page for <b>G-Earth2</b></h2>
<b>Webstart:</b> <a href='G_Earth.jnlp' onclick="return launchApplication('G_Earth.jnlp');">click to launch this app as webstart</a><br><hr><br>
<!-- Applet will be inserted here -->
<div id='javafx-app-placeholder'></div>
</body></html>

Binary file not shown.

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<jnlp spec="1.0" xmlns:jfx="http://javafx.com" href="G_Earth.jnlp">
<information>
<title>G-Earth</title>
<vendor>Unknown</vendor>
<description>G-Earth2</description>
<offline-allowed/>
</information>
<resources>
<j2se version="1.6+" href="http://java.sun.com/products/autodl/j2se"/>
<jar href="G_Earth.jar" size="63002" download="eager" />
</resources>
<jfx:javafx-desc width="600" height="400" main-class="main.Main" name="G-Earth2" />
<update check="background"/>
</jnlp>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Tab?>
<?import javafx.scene.control.TabPane?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.layout.VBox?>
<!--maxHeight="19.0" minHeight="19.0"-->
<VBox xmlns="http://javafx.com/javafx/8.0.112" xmlns:fx="http://javafx.com/fxml/1" fx:controller="main.ui.GEarthController">
<Pane fx:id="mover" maxHeight="0.0" minHeight="0.0" prefWidth="200.0" />
<TabPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" prefHeight="295.0" prefWidth="565.0" tabClosingPolicy="UNAVAILABLE">
<tabs>
<Tab text="Connection">
<content>
<fx:include fx:id="connection" source="connection/Connection.fxml" />
</content>
</Tab>
<Tab text="Logger">
<content>
<fx:include fx:id="logger" source="logger/Logger.fxml" />
</content></Tab>
<Tab text="Injection">
<content>
<fx:include fx:id="injection" source="injection/Injection.fxml" />
</content></Tab>
<Tab text="Tools">
<content>
<fx:include fx:id="tools" source="tools/Tools.fxml" />
</content>
</Tab>
<Tab disable="true" text="Scheduler" />
<Tab disable="true" text="Settings" />
<Tab disable="true" text="Extensions" />
<Tab disable="true" text="Info" />
</tabs>
</TabPane>
</VBox>

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,893 @@
.root {
-fx-body-color : #F5F5F5;
-fx-outer-border : #cecece;
}
.button,.menu-button,.toggle-button,.split-menu-button {
-fx-font-size: 14;
-fx-background-radius: 4;
-fx-border-radius: 4;
-fx-pref-height: 30;
-fx-min-width: 30;
}
.button,.menu-button,.split-menu-button,.toggle-button,.number-button {
-fx-background-insets: 0, 0, -1, 0;
}
.split-menu-button > .label {
-fx-border-radius: 4 0 0 4;
-fx-background-radius: 3 0 0 3;
}
.split-menu-button > .arrow-button {
-fx-border-radius: 0 4 4 0;
-fx-background-radius: 0 3 3 0;
}
.lg {
-fx-min-height: 46;
-fx-max-height: 46;
-fx-font-size: 18;
}
.sm {
-fx-min-height: 30;
-fx-max-height: 30;
}
.xs {
-fx-min-height: 22;
-fx-max-height: 22;
-fx-font-size: 10;
}
.primary .arrow,
.success .arrow,
.info .arrow,
.warning .arrow,
.danger .arrow {
-fx-background-color: transparent, white;
}
.primary > .label,
.success > .label,
.info > .label,
.warning > .label,
.danger > .label {
-fx-text-fill: white;
}
.action-btn {
-fx-min-width: 80;
}
/*positions*/
/*first*/
.button.first, .menu-button.first, .toggle-button.first, .text-field.first, .text-area.first {
-fx-border-radius: 4 0 0 4;
-fx-background-radius: 4 0 0 4;
}
.split-menu-button.first > .arrow-button, .split-menu-button.middle > .arrow-button {
-fx-border-radius: 0;
-fx-background-radius: 0;
}
VBox > .button.first,
VBox > .menu-button.first,
VBox > .toggle-button.first,
VBox > .split-menu-button.first,
VBox > .text-field.first,
VBox > .text-area.first {
-fx-border-radius: 4 4 0 0;
-fx-background-radius: 4 4 0 0;
}
VBox > .split-menu-button.first > .label {
-fx-border-radius: 4 0 0 0;
-fx-background-radius: 3 0 0 0;
}
VBox > .split-menu-button.first > .arrow-button {
-fx-border-radius: 0 4 0 0;
-fx-background-radius: 0 3 0 0;
}
/*middle*/
.middle {
-fx-border-radius: 0;
-fx-background-radius: 0;
}
/*last*/
.split-menu-button.middle > .label, .split-menu-button.last > .label {
-fx-border-radius: 0;
-fx-background-radius: 0;
}
.split-menu-button.last {
-fx-border-radius: 0 4 4 0;
-fx-background-radius: 0 4 4 0;
}
.button.middle, .text-field.middle, .text-area.middle, .split-menu-button.middle, .toggle-button.middle {
-fx-border-radius: 0;
-fx-background-radius: 0;
}
.button.last, .text-field.last, .text-area.last, .split-menu-button.last, .toggle-button.last, .menu-button.last {
-fx-border-radius: 0 4 4 0;
-fx-background-radius: 0 4 4 0;
}
VBox > .button.last,
VBox > .menu-button.last,
VBox > .toggle-button.last,
VBox > .split-menu-button.last,
VBox > .text-field.last,
VBox > .text-area.last {
-fx-border-radius: 0 0 4 4;
-fx-background-radius: 0 0 4 4;
}
VBox > .split-menu-button.last > .label {
-fx-border-radius: 0 0 0 4;
-fx-background-radius: 0 0 0 3;
}
VBox > .split-menu-button.last > .arrow-button {
-fx-border-radius: 0 0 4 0;
-fx-background-radius: 0 0 3 0;
}
/*button styles*/
/*default button settings*/
/*bgcolor setting*/
.color-picker,.date-picker > .arrow-button,
.number-button,.left-arrow-button,.right-arrow-button,
.button,.split-menu-button,.toggle-button,.menu-button,
.font-menu-button, .split-menu-button > .label, .split-menu-button > .arrow-button {
-fx-background-color: white;
}
.color-picker,.date-picker > .arrow-button,
.button,.menu-button,.toggle-button,.number-button,.left-arrow-button,.right-arrow-button,
.font-menu-button,
.split-menu-button > .label,.split-menu-button > .arrow-button {
-fx-border-color: #cccccc;
-fx-text-fill: #333333;
}
/*just for the special split menu button*/
.split-menu-button > .label {
-fx-border-width: 1 0 1 1;
}
/*for date picker arrow button*/
.date-picker > .arrow-button {
-fx-border-radius: 0 4 4 0;
}
.combo-box > .arrow-button, .choice-box > .arrow-button {
-fx-border-width: 0;
}
/*hover state*/
.color-picker:hover,
.date-picker:hover > .arrow-button,
.combo-box:hover,.choice-box:hover,
.number-button:hover,.left-arrow-button:hover,.right-arrow-button:hover,
.button:hover,.menu-button:hover,.toggle-button:hover,
.font-menu-button:hover,
.split-menu-button > .label:hover, .split-menu-button > .arrow-button:hover {
-fx-background-color: #e6e6e6;
-fx-border-color: #acacac;
}
/*pressed selected*/
.color-picker:pressed,.color-picker:selected,
.number-button:pressed,.number-button:selected,
.date-picker:pressed > .arrow-button,
.combo-box:pressed > .arrow-button,.combo-box:selected > .arrow-button,
.choice-box:pressed > .arrow-button,.choice-box:selected > .arrow-button,
.font-menu-button:pressed,.font-menu-button:selected,
.left-arrow-button:pressed,.left-arrow-button:selected,
.right-arrow-button:pressed,.right-arrow-button:selected,
.button:pressed, .button:selected,.menu-button:pressed,.menu-button:selected
,.toggle-button:pressed,.toggle-button:selected,
.split-menu-button:pressed > .label, .split-menu-button > .arrow-button:pressed {
-fx-background-color: #e6e6e6;
-fx-border-color: #acacac;
-fx-effect: innershadow(gaussian, #adadad, 10, 0, 0, 3);
}
/*primary*/
.button.primary,.split-menu-button.primary,.toggle-button.primary,.menu-button.primary,
.split-menu-button.primary > .label, .split-menu-button.primary > .arrow-button {
-fx-background-color: #337ab7;
}
.button.primary,.menu-button.primary,.toggle-button.primary,
.split-menu-button.primary > .label,.split-menu-button.primary > .arrow-button {
-fx-border-color: #2e6da4;
-fx-text-fill: white;
}
/*hover state*/
.button.primary:hover,.menu-button.primary:hover,.toggle-button.primary:hover,
.split-menu-button.primary > .label:hover, .split-menu-button.primary > .arrow-button:hover {
-fx-border-color: #204d74;
-fx-background-color: #286090;
}
/*pressed selected*/
.button.primary:pressed, .button.primary:selected,
.menu-button.primary:pressed,.menu-button.primary:selected
,.toggle-button.primary:pressed,.toggle-button.primary:selected,
.split-menu-button.primary:pressed > .label, .split-menu-button.primary > .arrow-button:pressed {
-fx-background-color: #286090;
-fx-border-color: #204d74;
-fx-effect: innershadow(gaussian, #204d74, 10, 0, 0, 3);
}
/*success*/
.button.success,.split-menu-button.success,.toggle-button.success,.menu-button.success,
.split-menu-button.success > .label, .split-menu-button.success > .arrow-button {
-fx-background-color: #5cb85c;
}
.button.success,.menu-button.success,.toggle-button.success,
.split-menu-button.success > .label,.split-menu-button.success > .arrow-button {
-fx-border-color: #4cae4c;
-fx-text-fill: white;
}
/*hover state*/
.button.success:hover,.menu-button.success:hover,.toggle-button.success:hover,
.split-menu-button.success > .label:hover, .split-menu-button.success > .arrow-button:hover {
-fx-border-color: #398439;
-fx-background-color: #449d44;
}
/*pressed selected*/
.button.success:pressed, .button.success:selected,
.menu-button.success:pressed,.menu-button.success:selected
,.toggle-button.success:pressed,.toggle-button.success:selected,
.split-menu-button.success:pressed > .label, .split-menu-button.success > .arrow-button:pressed {
-fx-background-color: #449d44;
-fx-border-color: #398439;
-fx-effect: innershadow(gaussian, #398439, 10, 0, 0, 3);
}
/*info*/
.button.info,.split-menu-button.info,.toggle-button.info,.menu-button.info,
.split-menu-button.info > .label, .split-menu-button.info > .arrow-button {
-fx-background-color: #5bc0de;
}
.button.info,.menu-button.info,.toggle-button.info,
.split-menu-button.info > .label,.split-menu-button.info > .arrow-button {
-fx-border-color: #46b8da;
-fx-text-fill: white;
}
/*hover state*/
.button.info:hover,.menu-button.info:hover,.toggle-button.info:hover,
.split-menu-button.info > .label:hover, .split-menu-button.info > .arrow-button:hover {
-fx-border-color: #269abc;
-fx-background-color: #31b0d5;
}
/*pressed selected*/
.button.info:pressed, .button.info:selected,
.menu-button.info:pressed,.menu-button.info:selected
,.toggle-button.info:pressed,.toggle-button.info:selected,
.split-menu-button.info:pressed > .label, .split-menu-button.info > .arrow-button:pressed {
-fx-background-color: #31b0d5;
-fx-border-color: #269abc;
-fx-effect: innershadow(gaussian, #269abc, 10, 0, 0, 3);
}
/*warning*/
.button.warning,.split-menu-button.warning,.toggle-button.warning,.menu-button.warning,
.split-menu-button.warning > .label, .split-menu-button.warning > .arrow-button {
-fx-background-color: #f0ad4e;
}
.button.warning,.menu-button.warning,.toggle-button.warning,
.split-menu-button.warning > .label,.split-menu-button.warning > .arrow-button {
-fx-border-color: #eea236;
-fx-text-fill: white;
}
/*hover state*/
.button.warning:hover,.menu-button.warning:hover,.toggle-button.warning:hover,
.split-menu-button.warning > .label:hover, .split-menu-button.warning > .arrow-button:hover {
-fx-border-color: #d58512;
-fx-background-color: #ec971f;
}
/*pressed selected*/
.button.warning:pressed, .button.warning:selected,
.menu-button.warning:pressed,.menu-button.warning:selected
,.toggle-button.warning:pressed,.toggle-button.warning:selected,
.split-menu-button.warning:pressed > .label, .split-menu-button.warning > .arrow-button:pressed {
-fx-background-color: #ec971f;
-fx-border-color: #d58512;
-fx-effect: innershadow(gaussian, #d58512, 10, 0, 0, 3);
}
/*danger*/
.button.danger,.split-menu-button.danger,.toggle-button.danger,.menu-button.danger,
.split-menu-button.danger > .label, .split-menu-button.danger > .arrow-button {
-fx-background-color: #d9534f;
}
.button.danger,.menu-button.danger,.toggle-button.danger,
.split-menu-button.danger > .label,.split-menu-button.danger > .arrow-button {
-fx-border-color: #d43f3a;
-fx-text-fill: white;
}
/*hover state*/
.button.danger:hover,.menu-button.danger:hover,.toggle-button.danger:hover,
.split-menu-button.danger > .label:hover, .split-menu-button.danger > .arrow-button:hover {
-fx-border-color: #ac2925;
-fx-background-color: #c9302c;
}
/*pressed selected*/
.button.danger:pressed, .button.danger:selected,
.menu-button.danger:pressed,.menu-button.danger:selected
,.toggle-button.danger:pressed,.toggle-button.danger:selected,
.split-menu-button.danger:pressed > .label, .split-menu-button.danger > .arrow-button:pressed {
-fx-border-color: #ac2925;
-fx-background-color: #c9302c;
-fx-effect: innershadow(gaussian, #ac2925, 10, 0, 0, 3);
}
.menu-item {
-fx-min-width: 200;
}
.menu-item:focused {
-fx-background-color: #f5f5f5;
}
.menu-item:focused > * {
-fx-text-fill: #262626;
}
.menu-item:focused .arrow {
-fx-background-color: #333333;
}
.check-menu-item:checked:hover > .left-container > .check,
.check-menu-item:checked:focused > .left-container > .check,
.radio-menu-item:checked:hover > .left-container > .radio,
.radio-menu-item:checked:focused > .left-container > .radio {
-fx-background-color: #333333;
}
.context-menu {
-fx-border-radius: 4;
-fx-background-radius: 4;
-fx-border-color: #bebec0;
}
.context-menu > * {
-fx-padding: 5 0 5 0;
}
.separator {
-fx-padding: 5 0 5 0;
}
.text-field {
-fx-pref-height: 30;
}
.combo-box, .choice-box {
-fx-background-insets: 0;
-fx-border-color: #cecece;
-fx-padding: -1;
-fx-border-width: 1;
}
.combo-box, .choice-box, .color-picker, .date-picker {
-fx-border-radius: 4;
-fx-background-radius: 4;
-fx-pref-height: 30;
}
.combo-box:editable > .arrow-button {
-fx-background-color: white;
}
.combo-box:editable > .arrow-button:hover {
-fx-background-color: #e6e6e6;
}
.combo-box:editable > .arrow-button:pressed {
-fx-effect: innershadow(gaussian, #adadad, 10, 0, 0, 3);
}
.combo-box > .text-input, .date-picker > .text-input {
-fx-background-radius: 4 0 0 4;
-fx-border-width: 0;
}
.text-field, .text-area {
-fx-border-color: #cccccc;
-fx-background-color: white;
-fx-border-radius: 4;
-fx-background-radius: 4;
-fx-effect: innershadow(gaussian, transparent, 0, 0, 0, 0);
}
.text-field:focused, .text-area:focused {
-fx-border-color: #66afe9;
-fx-effect: dropshadow(gaussian, #66afe9, 10, 0, 0, 0);
}
.text-area .scroll-pane, .text-area .scroll-pane .content {
-fx-background-color: white;
-fx-background-radius: 4;
}
.tab-pane .tab-header-background {
-fx-background-color: #f4f4f4;
}
.tab-pane.plain .tab-header-background {
-fx-background-color: transparent;
}
.tab-pane .tab-header-area .tab {
-fx-border-radius: 4 4 0 0;
-fx-background-radius: 5 5 0 0;
-fx-background-color: transparent;
-fx-border-color: transparent;
-fx-padding: 3 10 5 10;
-fx-background-insets: 0;
}
.tab-pane .tab-header-area .tab .tab-label {
-fx-text-fill: #337ab7;
}
.tab-pane .tab-header-area .tab:hover {
-fx-background-color: #eeeeee;
}
.tab-pane .tab-header-area .tab:selected {
-fx-focus-color: transparent;
-fx-border-color: #dddddd #dddddd white #dddddd;
-fx-background-color: white;
}
.tab-pane .tab-header-area .tab:selected .tab-label {
-fx-text-fill: #333333;
}
.tab-pane > .tab-content-area {
-fx-background-color: white;
}
.tab-pane .tab-header-area .tab .tab-label {
-fx-focus-color: transparent;
}
.tab-pane:focused > .tab-header-area > .headers-region > .tab:selected .focus-indicator {
-fx-border-color: transparent;
}
.tab-pane > .tab-header-area > .headers-region > .tab > .tab-container > .tab-close-button {
-fx-background-color: #337ab7;
}
.tab-pane > .tab-header-area > .headers-region > .tab:selected > .tab-container > .tab-close-button {
-fx-background-color: #333333;
}
.tab-pane > .tab-header-area > .headers-region > .tab > .tab-container > .tab-close-button:hover {
-fx-background-color: red;
-fx-cursor: hand;
}
.scroll-bar {
-fx-background-color: transparent;
-fx-background-radius: 0;
-fx-block-increment: 50;
}
.corner {
-fx-background-color: transparent;
}
.scroll-bar .decrement-button, .scroll-bar .decrement-arrow {
visibility: hidden;
-fx-pref-height: 1;
-fx-pref-width: 1;
}
.scroll-bar .increment-button, .scroll-bar .increment-arrow {
visibility: hidden;
-fx-pref-height: 1;
-fx-pref-width: 1;
}
.scroll-bar:vertical {
-fx-pref-width: 10;
}
.scroll-bar:horizontal {
-fx-pref-height: 10;
}
.scroll-bar:horizontal .track,
.scroll-bar:vertical .track {
-fx-background-color: transparent;
-fx-border-color: transparent;
-fx-background-radius: 5;
}
.scroll-bar:vertical .track-background,
.scroll-bar:horizontal .track-background {
-fx-background-color: transparent;
-fx-background-insets: 0;
-fx-background-radius: 5;
}
.scroll-bar:horizontal .thumb {
-fx-background-color: #c9c9c9;
-fx-background-insets: 2 0 2 0;
-fx-background-radius: 5;
}
.scroll-bar:vertical .thumb {
-fx-background-color: #c9c9c9;
-fx-background-insets: 0 2 0 2;
-fx-background-radius: 5;
}
.scroll-bar:horizontal .thumb:hover,
.scroll-bar:vertical .thumb:hover {
-fx-background-color: #b5b5b5;
}
.scroll-bar:horizontal .thumb:pressed,
.scroll-bar:vertical .thumb:pressed {
-fx-background-color: #a0a0a0;
}
.scroll-bar:vertical .increment-button, .scroll-bar:vertical .decrement-button {
-fx-background-color: transparent;
-fx-background-radius: 5;
-fx-padding: 5;
}
.scroll-bar:horizontal .increment-button, .scroll-bar:horizontal .decrement-button {
-fx-background-color: transparent;
-fx-background-radius: 5;
-fx-padding: 5;
}
.scroll-bar:vertical:focused,
.scroll-bar:horizontal:focused {
-fx-background-color: transparent, rgb(96, 96, 96), rgb(96, 96, 96);
}
.menu-bar {
-fx-background-color: white;
}
.menu-bar > .container > .menu-button {
-fx-background-radius: 0;
-fx-background-insets: 0;
-fx-border-width: 0;
-fx-border-radius: 0;
}
.menu-bar > .container > .menu-button:hover,
.menu-bar > .container > .menu-button:showing {
-fx-background-color: #56c0e0;
}
.color-palette {
-fx-background-color: white;
}
.pagination > .pagination-control > .control-box {
-fx-spacing: -1;
}
.pagination > .pagination-control > .control-box > .left-arrow-button {
-fx-border-radius: 3 0 0 3;
-fx-border-insets: 0 0 0 7;
-fx-background-insets: 0 0 0 7, 0 0 0 5, 1 1 1 6, 2 2 2 7;
}
.pagination > .pagination-control > .control-box > .right-arrow-button {
-fx-border-radius: 0 3 3 0;
-fx-border-insets: 0 7 0 0;
-fx-background-insets: 0 7 -1 0, 0 5 0 0, 1 6 1 1, 2 7 2 2;
}
.pagination > .pagination-control > .control-box > .number-button {
-fx-background-radius: 0;
-fx-border-radius: 0;
}
.progress-bar > .track {
-fx-pref-height: 10;
-fx-background-radius: 3;
-fx-effect: innershadow(gaussian, #e4e4e4, 4, 0, 0, 1);
-fx-background-color: #f5f5f5;
}
.progress-bar > .bar {
-fx-background-insets: 0;
-fx-background-color: #337ab7;
}
.progress-bar.success > .bar {
-fx-background-insets: 0;
-fx-background-color: #5cb85c;
}
.progress-bar.info > .bar {
-fx-background-insets: 0;
-fx-background-color: #5bc0de;
}
.progress-bar.warning > .bar {
-fx-background-insets: 0;
-fx-background-color: #f0ad4e
}
.progress-bar.danger > .bar {
-fx-background-insets: 0;
-fx-background-color: #d9534f;
}
.tooltip {
-fx-background: white;
-fx-text-fill: #333333;
-fx-background-color: white;
-fx-background-radius: 4px;
-fx-border-radius: 4px;
-fx-border-color: #C0C0C0;
-fx-background-insets: 0;
-fx-padding: 0.667em 0.75em 0.667em 0.75em; /* 10px */
-fx-effect: dropshadow(three-pass-box, rgba(0, 0, 0, 0.5), 10, 0.0, 0, 3);
-fx-font-size: 0.85em;
}
.tooltip.success {
-fx-background: #dff0d8;
-fx-background-color: #dff0d8;
-fx-text-fill: #99bb96;
-fx-border-color: #d6e9c6;
}
.tooltip.info {
-fx-background: #d8ecf6;
-fx-background-color: #d8ecf6;
-fx-text-fill: #31708f;
-fx-border-color: #bce8f1;
}
.tooltip.warning {
-fx-background: #fcf8e3;
-fx-background-color: #fcf8e3;
-fx-text-fill: #8a6e3c;
-fx-border-color: #faebcc;
}
.tooltip.danger {
-fx-background: #f2dede;
-fx-background-color: #f2dede;
-fx-text-fill: #a94442;
-fx-border-color: #ebccd1;
}
.titled-pane > .title {
-fx-background-color: #f5f5f5;
-fx-border-color: #dddddd;
/*-fx-background-insets: 5, 1, 5;*/
-fx-background-radius: 3 3 0 0, 2 2 0 0, 1 1 0 0;
-fx-border-radius: 3 3 0 0, 2 2 0 0, 1 1 0 0;
-fx-padding: 11
}
.titled-pane > .content {
-fx-background-color: white;
-fx-background-radius: 0 0 4 4;
-fx-border-radius: 0 0 4 4;
-fx-border-color: #dddddd;
/*-fx-padding: -11;*/
}
.titled-pane.primary {
-fx-text-fill: white;
}
.titled-pane.primary > .title {
-fx-background-color: #337ab7;
-fx-border-color: #337ab7;
}
.titled-pane.primary > .content {
-fx-border-color: #337ab7;
}
.titled-pane.success .arrow,
.titled-pane.info .arrow,
.titled-pane.warning .arrow,
.titled-pane.danger .arrow {
-fx-background-color: -fx-mark-highlight-color, -fx-mark-color;
}
.titled-pane.success {
-fx-text-fill: #3c763d;
}
.titled-pane.success > .title {
-fx-background-color: #dff0d8;
-fx-border-color: #d6e9c6;
}
.titled-pane.success > .content {
-fx-border-color: #d6e9c6;
}
.titled-pane.info {
-fx-text-fill: #31708f;
}
.titled-pane.info > .title {
-fx-background-color: #d9edf7;
-fx-border-color: #bce8f1;
}
.titled-pane.info > .content {
-fx-border-color: #bce8f1;
}
.titled-pane.warning {
-fx-text-fill: #8a6d3b;
}
.titled-pane.warning > .title {
-fx-background-color: #fcf8e3;
-fx-border-color: #faebcc;
}
.titled-pane.warning > .content {
-fx-border-color: #faebcc;
}
.titled-pane.danger {
-fx-text-fill: #a94442;
}
.titled-pane.danger > .title {
-fx-background-color: #f2dede;
-fx-border-color: #eacbd0;
}
.titled-pane.danger > .content {
-fx-border-color: #eacbd0;
}
.accordion > .titled-pane > .title,
.accordion > .titled-pane > .content {
-fx-background-radius: 0;
-fx-border-radius: 0;
}
.tool-bar:vertical { /* left */
-fx-border-color: transparent #dddddd transparent transparent;
}
.tool-bar { /* top */
-fx-background-color: white;
-fx-border-color: transparent transparent #dddddd transparent;
}
.tool-bar:vertical {
-fx-background-insets: 0, 0 1 0 0;
}
/*table view columns*/
.filler,.column-header,.show-hide-columns-button {
-fx-background-color: #dddddd, white, white;
}
.show-hide-columns-button {
-fx-border-width: 0;
-fx-background-insets: 0 0 1 1;
}
.column-header:hover,.show-hide-columns-button:hover {
-fx-background-color: #dddddd, white, #f8f8f8;
}
.column-header-background > .filler {
-fx-border-color: transparent #dddddd transparent transparent;
-fx-border-insets: 0 1 0 0;
}
.column-drag-header {
-fx-background-color: #2fb254;
}
/*split pane*/
.split-pane > .split-pane-divider {
-fx-background-color: white;
-fx-border-color: #eeeeee;
-fx-pref-width: 8;
}
.split-pane:horizontal > .split-pane-divider {
-fx-background-insets: 0, 0 1 0 1;
-fx-border-width: 0 1 0 1;
}
/* vertical the two nodes are placed on top of each other. */
.split-pane:vertical > .split-pane-divider {
-fx-background-insets: 0, 1 0 1 0;
-fx-border-width: 1 0 1 0;
}
.split-pane > .split-pane-divider:hover {
-fx-background-color: #E0E0E0;
}
/*******************************************************************************
* *
* CheckBox *
* *
******************************************************************************/
.check-box > .box {
-fx-background-radius: 3;
/*-fx-padding: 0.166667em 0.166667em 0.25em 0.25em; !* 2 2 3 3 *!*/
-fx-padding:0;
-fx-border-color: #56c0e0;
-fx-border-radius: 3;
-fx-background-color: white;
}
.check-box > .box > .mark {
-fx-background-color: null;
-fx-padding: 0.416667em 0.416667em 0.5em 0.5em; /* 5 5 6 6 */
-fx-shape: "M927.936 272.992l-68.288-68.288c-12.608-12.576-32.96-12.576-45.536 0l-409.44 409.44-194.752-196.16c-12.576-12.576-32.928-12.576-45.536 0l-68.288 68.288c-12.576 12.608-12.576 32.96 0 45.536l285.568 287.488c12.576 12.576 32.96 12.576 45.536 0l500.736-500.768c12.576-12.544 12.576-32.96 0-45.536z";
-fx-background-insets: -3 -3 1 0;
}
.check-box {
-fx-label-padding: 0.2em 0.0em 0.3em 0.416667em; /* 0 0 0 5 */
-fx-text-fill: -fx-text-background-color;
-fx-padding: 0 0 2 0;
}
.check-box:indeterminate > .box {
-fx-padding: 0;
}
.check-box:selected > .box > .mark {
-fx-background-color: linear-gradient(to bottom, #56c0e0, #40b8dc);
}
/*******************************************************************************
* *
* RadioButton *
* *
******************************************************************************/
.radio-button {
-fx-label-padding: 0.0em 0.0em 0.1em 0.416667em; /* 0 0 0 5 */
-fx-text-fill: -fx-text-background-color;
-fx-padding: 0 0 .5 0;
}
.radio-button > .radio,
.radio-button:focused > .radio {
-fx-border-color: #56c0e0;
-fx-border-radius: 1em;
-fx-background-radius: 1.0em; /* large value to make sure this remains circular */
-fx-padding: 1 2 3 2;
-fx-background-color: white;
}
.radio-button > .radio > .dot {
-fx-background-color: transparent;
-fx-background-radius: 1.0em; /* large value to make sure this remains circular */
-fx-padding: 0.333333em; /* 4 -- radius of the inner black dot when selected */
-fx-background-insets: 3 2 1 2;
}
.radio-button:selected > .radio,.radio-button:hover > .radio {
-fx-fill-color: #56c0e0;
}
.radio-button:pressed > .radio {
-fx-background-color: #50c0e2;
}
.radio-button:selected > .radio > .dot {
-fx-background-color: #56c0e0;
}
/*common things*/
.check-box:hover > .box,
.check-box:selected > .box,
.radio-button:hover > .radio,
.radio-button:selected > .radio {
-fx-background-color: linear-gradient(to bottom, white, #efefef);
}
.check-box:pressed > .box,
.radio-button:pressed > .radio {
-fx-background-color: #50c0e2;
}

View File

@ -0,0 +1,209 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ComboBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.text.Font?>
<GridPane alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="262.0" prefWidth="565.0" xmlns="http://javafx.com/javafx/8.0.112" xmlns:fx="http://javafx.com/fxml/1" fx:controller="main.ui.connection.ConnectionForm">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<GridPane alignment="CENTER" GridPane.hgrow="SOMETIMES" GridPane.vgrow="SOMETIMES">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="364.0" minWidth="10.0" prefWidth="325.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="279.0" minWidth="10.0" prefWidth="252.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<GridPane GridPane.columnIndex="1">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints maxHeight="32.0" minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="32.0" minHeight="10.0" prefHeight="29.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="45.0" minHeight="10.0" prefHeight="43.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<GridPane>
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="120.0" minWidth="10.0" prefWidth="68.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="188.0" minWidth="10.0" prefWidth="184.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Label text="Port:" GridPane.halignment="CENTER" GridPane.valignment="CENTER" />
<ComboBox fx:id="inpPort" editable="true" GridPane.columnIndex="1">
<GridPane.margin>
<Insets right="15.0" />
</GridPane.margin>
</ComboBox>
</children>
</GridPane>
<GridPane layoutX="10.0" layoutY="10.0" GridPane.rowIndex="1">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="120.0" minWidth="10.0" prefWidth="68.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="188.0" minWidth="10.0" prefWidth="184.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Label text="Host:" GridPane.halignment="CENTER" GridPane.valignment="CENTER" />
<ComboBox fx:id="inpHost" editable="true" GridPane.columnIndex="1">
<GridPane.margin>
<Insets right="15.0" />
</GridPane.margin>
</ComboBox>
</children>
</GridPane>
<Button fx:id="btnConnect" alignment="CENTER" maxWidth="1.7976931348623157E308" onAction="#btnConnect_clicked" text="Connect" GridPane.halignment="CENTER" GridPane.rowIndex="2" GridPane.valignment="CENTER">
<GridPane.margin>
<Insets left="15.0" right="15.0" />
</GridPane.margin></Button>
</children>
<opaqueInsets>
<Insets />
</opaqueInsets>
<GridPane.margin>
<Insets bottom="6.0" top="22.0" />
</GridPane.margin>
</GridPane>
<GridPane style="-fx-border-color: #888888; -fx-border-radius: 5px;">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="140.0" minWidth="10.0" prefWidth="103.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="191.0" minWidth="10.0" prefWidth="190.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<GridPane.margin>
<Insets bottom="12.0" left="20.0" right="10.0" top="18.0" />
</GridPane.margin>
<children>
<Label text="Public key:" textFill="#000000cc">
<GridPane.margin>
<Insets left="10.0" />
</GridPane.margin>
</Label>
<Label text="Private key:" textFill="#000000cc" GridPane.rowIndex="1">
<GridPane.margin>
<Insets left="10.0" />
</GridPane.margin>
</Label>
<TextField editable="false" GridPane.columnIndex="1">
<opaqueInsets>
<Insets />
</opaqueInsets>
<GridPane.margin>
<Insets left="5.0" right="10.0" />
</GridPane.margin>
</TextField>
<TextField editable="false" GridPane.columnIndex="1" GridPane.rowIndex="1">
<GridPane.margin>
<Insets left="5.0" right="10.0" />
</GridPane.margin>
</TextField>
</children>
<padding>
<Insets bottom="7.0" top="7.0" />
</padding>
</GridPane>
</children>
</GridPane>
<GridPane alignment="CENTER" GridPane.rowIndex="1">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="283.0" minWidth="10.0" prefWidth="197.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="380.0" minWidth="10.0" prefWidth="380.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<GridPane>
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints maxHeight="62.0" minHeight="10.0" prefHeight="53.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="107.0" minHeight="10.0" prefHeight="85.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Label text="Connection state:" textFill="#000000ba" GridPane.valignment="BOTTOM">
<GridPane.margin>
<Insets bottom="5.0" left="2.0" />
</GridPane.margin>
<font>
<Font size="12.0" />
</font>
</Label>
<Label fx:id="lblState" alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-border-color: #888888; -fx-border-radius: 5px;" text="Not connected" textAlignment="CENTER" textFill="#000000d1" GridPane.halignment="CENTER" GridPane.hgrow="ALWAYS" GridPane.rowIndex="1" GridPane.valignment="CENTER" GridPane.vgrow="ALWAYS" />
</children>
<GridPane.margin>
<Insets bottom="14.0" left="20.0" />
</GridPane.margin>
</GridPane>
<GridPane style="-fx-border-color: #888888; -fx-border-radius: 5px; " GridPane.columnIndex="1">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="140.0" minWidth="10.0" prefWidth="103.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="191.0" minWidth="10.0" prefWidth="190.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<GridPane.margin>
<Insets bottom="12.0" left="20.0" right="10.0" top="18.0" />
</GridPane.margin>
<children>
<Label text="Game host:" textFill="#000000cc">
<GridPane.margin>
<Insets left="10.0" />
</GridPane.margin>
</Label>
<Label text="Port:" textFill="#000000cc" GridPane.rowIndex="1">
<GridPane.margin>
<Insets left="10.0" />
</GridPane.margin>
</Label>
<TextField fx:id="outHost" editable="false" GridPane.columnIndex="1">
<opaqueInsets>
<Insets />
</opaqueInsets>
<GridPane.margin>
<Insets left="5.0" right="10.0" />
</GridPane.margin>
</TextField>
<TextField fx:id="outPort" editable="false" GridPane.columnIndex="1" GridPane.rowIndex="1">
<GridPane.margin>
<Insets left="5.0" right="10.0" />
</GridPane.margin>
</TextField>
</children>
<padding>
<Insets bottom="7.0" top="7.0" />
</padding>
</GridPane>
</children>
<GridPane.margin>
<Insets />
</GridPane.margin>
</GridPane>
</children>
</GridPane>

View File

@ -0,0 +1,76 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.text.Font?>
<?import javafx.scene.text.Text?>
<GridPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="262.0" prefWidth="565.0" xmlns="http://javafx.com/javafx/8.0.112" xmlns:fx="http://javafx.com/fxml/1" fx:controller="main.ui.injection.InjectionForm">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints maxHeight="232.0" minHeight="10.0" prefHeight="36.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="232.0" minHeight="10.0" prefHeight="194.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="121.0" minHeight="10.0" prefHeight="32.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<GridPane GridPane.rowIndex="0">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Text fx:id="lbl_corrruption" fill="#ee0404b2" strokeType="OUTSIDE" strokeWidth="0.0" text="isCorrupted: True">
<font>
<Font name="System Italic" size="11.0" />
</font>
</Text>
<Text fx:id="lbl_pcktInfo" fill="#000000b2" nodeOrientation="LEFT_TO_RIGHT" strokeType="OUTSIDE" strokeWidth="0.0" text="header (id:NULL, length:0)" GridPane.columnIndex="1" GridPane.halignment="RIGHT">
<font>
<Font name="System Italic" size="11.0" />
</font>
</Text>
</children>
<GridPane.margin>
<Insets left="13.0" right="13.0" top="4.0" />
</GridPane.margin>
</GridPane>
<TextArea fx:id="inputPacket" prefHeight="185.0" prefWidth="545.0" wrapText="true" GridPane.rowIndex="1">
<GridPane.margin>
<Insets bottom="5.0" left="10.0" right="10.0" />
</GridPane.margin>
</TextArea>
<GridPane GridPane.rowIndex="2">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Button fx:id="btn_sendToServer" disable="true" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#sendToServer_clicked" text="Send to server" GridPane.halignment="CENTER" GridPane.valignment="CENTER">
<GridPane.margin>
<Insets bottom="5.0" left="10.0" right="10.0" top="5.0" />
</GridPane.margin>
</Button>
<Button fx:id="btn_sendToClient" disable="true" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#sendToClient_clicked" text="Send to client" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.valignment="CENTER">
<GridPane.margin>
<Insets bottom="5.0" left="10.0" right="10.0" top="5.0" />
</GridPane.margin>
</Button>
</children>
</GridPane>
</children>
<padding>
<Insets bottom="7.0" />
</padding>
</GridPane>

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.CheckBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.text.TextFlow?>
<GridPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="262.0" prefWidth="565.0" xmlns="http://javafx.com/javafx/8.0.112" xmlns:fx="http://javafx.com/fxml/1" fx:controller="main.ui.logger.LoggerForm">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="293.0" minWidth="10.0" prefWidth="242.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="390.0" minWidth="10.0" prefWidth="323.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<GridPane alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="5.0E9" prefWidth="5.0E9">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints maxHeight="138.0" minHeight="10.0" prefHeight="126.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="111.0" minHeight="10.0" prefHeight="109.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<VBox prefHeight="200.0" prefWidth="100.0" spacing="8.0">
<children>
<GridPane prefHeight="52.0" prefWidth="214.0">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="160.0" minWidth="10.0" prefWidth="132.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="110.0" minWidth="10.0" prefWidth="84.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<GridPane>
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Label text="Packet size limit:" />
<TextField fx:id="txtPacketLimit" text="8000" GridPane.rowIndex="1">
<GridPane.margin>
<Insets right="8.0" />
</GridPane.margin>
</TextField>
</children>
</GridPane>
<Button fx:id="btnUpdate" alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#updatePacketLimit" prefHeight="44.0" prefWidth="62.0" text="Update" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.hgrow="ALWAYS" GridPane.valignment="CENTER" GridPane.vgrow="ALWAYS">
<GridPane.margin>
<Insets bottom="-1.0" left="6.0" right="6.0" />
</GridPane.margin>
</Button>
</children>
</GridPane>
<CheckBox fx:id="cbx_blockIn" mnemonicParsing="false" text="Block Incoming" />
<CheckBox fx:id="cbx_blockOut" mnemonicParsing="false" text="Block Outgoing" />
</children>
</VBox>
<VBox alignment="BOTTOM_LEFT" prefHeight="99.0" prefWidth="198.0" spacing="8.0" GridPane.rowIndex="1">
<children>
<CheckBox fx:id="cbx_showAdditional" mnemonicParsing="false" selected="true" text="Show additional data" />
<CheckBox disable="true" mnemonicParsing="false" selected="true" text="Show packet structure" />
<CheckBox fx:id="cbx_splitPackets" mnemonicParsing="false" selected="true" text="Split packets" />
</children>
<GridPane.margin>
<Insets />
</GridPane.margin>
</VBox>
</children>
<GridPane.margin>
<Insets bottom="12.0" left="17.0" top="15.0" />
</GridPane.margin>
</GridPane>
<GridPane style="-fx-border-color: #888; -fx-border-radius: 5px;" GridPane.columnIndex="1">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints maxHeight="125.0" minHeight="10.0" prefHeight="33.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="233.0" minHeight="10.0" prefHeight="191.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<CheckBox fx:id="cbx_useLog" mnemonicParsing="false" selected="true" text="Use history log">
<GridPane.margin>
<Insets left="5.0" />
</GridPane.margin>
</CheckBox>
<ScrollPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-border-color: #888888; -fx-border-radius: 1px; -fx-background: #FFFFFF;" GridPane.hgrow="ALWAYS" GridPane.rowIndex="1" GridPane.vgrow="ALWAYS">
<TextFlow fx:id="txt_logField" style=" -fx-background-color: #FFFFFF;">
<GridPane.margin>
<Insets />
</GridPane.margin>
</TextFlow>
<padding>
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
</padding>
</ScrollPane>
</children>
<GridPane.margin>
<Insets bottom="10.0" left="15.0" right="15.0" top="10.0" />
</GridPane.margin>
<padding>
<Insets bottom="10.0" left="7.0" right="7.0" top="6.0" />
</padding>
</GridPane>
</children>
</GridPane>

View File

@ -0,0 +1,165 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.text.Font?>
<GridPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="262.0" prefWidth="565.0" xmlns="http://javafx.com/javafx/8.0.112" xmlns:fx="http://javafx.com/fxml/1" fx:controller="main.ui.tools.ToolsForm">
<rowConstraints>
<RowConstraints maxHeight="158.0" minHeight="10.0" prefHeight="134.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="141.0" minHeight="10.0" prefHeight="128.0" vgrow="SOMETIMES" />
</rowConstraints>
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="683.0" minWidth="10.0" prefWidth="276.0" />
</columnConstraints>
<children>
<GridPane>
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints maxHeight="53.0" minHeight="10.0" prefHeight="29.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="108.0" minHeight="10.0" prefHeight="100.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<GridPane style="-fx-border-color: #888888; -fx-border-radius: 5px;" GridPane.rowIndex="1">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="103.0" minWidth="10.0" prefWidth="73.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="159.0" minWidth="10.0" prefWidth="146.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="129.0" minWidth="10.0" prefWidth="89.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="148.0" minWidth="10.0" prefWidth="89.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="167.0" minWidth="10.0" prefWidth="146.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<GridPane.margin>
<Insets />
</GridPane.margin>
<children>
<Label alignment="CENTER" text="Integer:">
<GridPane.margin>
<Insets left="10.0" />
</GridPane.margin></Label>
<TextField fx:id="txt_intDecoded" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" GridPane.columnIndex="1" GridPane.hgrow="ALWAYS">
<GridPane.margin>
<Insets bottom="7.0" left="5.0" right="5.0" top="7.0" />
</GridPane.margin></TextField>
<Button fx:id="btnEncodeInt" disable="true" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#btnEncodeInt_clicked" text="Encode" GridPane.columnIndex="2" GridPane.halignment="CENTER">
<GridPane.margin>
<Insets bottom="7.0" left="5.0" right="5.0" top="7.0" />
</GridPane.margin></Button>
<Button fx:id="btnDecodeInt" disable="true" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#btnDecodeInt_clicked" text="Decode" GridPane.columnIndex="3" GridPane.halignment="CENTER">
<GridPane.margin>
<Insets bottom="7.0" left="5.0" right="5.0" top="7.0" />
</GridPane.margin></Button>
<TextField fx:id="txt_intEncoded" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" GridPane.columnIndex="4">
<GridPane.margin>
<Insets bottom="7.0" left="5.0" right="5.0" top="7.0" />
</GridPane.margin>
</TextField>
<Label alignment="CENTER" text="Ushort:" GridPane.rowIndex="1">
<GridPane.margin>
<Insets left="10.0" />
</GridPane.margin></Label>
<TextField fx:id="txt_ushortDecoded" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" GridPane.columnIndex="1" GridPane.hgrow="ALWAYS" GridPane.rowIndex="1">
<GridPane.margin>
<Insets bottom="7.0" left="5.0" right="5.0" top="7.0" />
</GridPane.margin></TextField>
<Button fx:id="btnEncodeUShort" disable="true" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#btnEncodeUShort_clicked" text="Encode" GridPane.columnIndex="2" GridPane.halignment="CENTER" GridPane.rowIndex="1">
<GridPane.margin>
<Insets bottom="7.0" left="5.0" right="5.0" top="7.0" />
</GridPane.margin></Button>
<Button fx:id="btnDecodeUshort" disable="true" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#btnDecodeUshort_clicked" text="Decode" GridPane.columnIndex="3" GridPane.halignment="CENTER" GridPane.rowIndex="1">
<GridPane.margin>
<Insets bottom="7.0" left="5.0" right="5.0" top="7.0" />
</GridPane.margin></Button>
<TextField fx:id="txt_ushortEncoded" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" GridPane.columnIndex="4" GridPane.rowIndex="1">
<GridPane.margin>
<Insets bottom="7.0" left="5.0" right="5.0" top="7.0" />
</GridPane.margin>
</TextField>
</children>
</GridPane>
<Label text="Encoding/decoding" textFill="#000000cc">
<GridPane.margin>
<Insets left="6.0" top="5.0" />
</GridPane.margin>
<font>
<Font name="System Italic" size="12.0" />
</font>
</Label>
</children>
<GridPane.margin>
<Insets left="10.0" right="10.0" top="5.0" />
</GridPane.margin>
</GridPane>
<GridPane layoutX="20.0" layoutY="15.0" GridPane.rowIndex="1">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints maxHeight="53.0" minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="104.0" minHeight="10.0" prefHeight="99.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<GridPane style="-fx-border-color: #888888; -fx-border-radius: 5px;" GridPane.rowIndex="1">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="190.0" minWidth="10.0" prefWidth="180.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="130.0" minWidth="10.0" prefWidth="90.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="118.0" minWidth="10.0" prefWidth="90.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="219.0" minWidth="10.0" prefWidth="180.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<GridPane.margin>
<Insets />
</GridPane.margin>
<children>
<Button disable="true" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" text="------&gt;" GridPane.columnIndex="1" GridPane.halignment="CENTER">
<GridPane.margin>
<Insets bottom="7.0" left="5.0" right="5.0" top="7.0" />
</GridPane.margin>
</Button>
<TextArea disable="true" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="200.0" prefWidth="200.0" GridPane.halignment="CENTER">
<GridPane.margin>
<Insets bottom="7.0" left="7.0" right="5.0" top="7.0" />
</GridPane.margin>
</TextArea>
<Button disable="true" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" text="&lt;------" GridPane.columnIndex="2" GridPane.halignment="CENTER">
<GridPane.margin>
<Insets bottom="7.0" left="5.0" right="5.0" top="7.0" />
</GridPane.margin>
</Button>
<TextArea disable="true" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="3" GridPane.halignment="CENTER">
<GridPane.margin>
<Insets bottom="7.0" left="5.0" right="7.0" top="7.0" />
</GridPane.margin>
</TextArea>
</children>
</GridPane>
<Label text="Packet &lt;-&gt; expression" textFill="#000000cc">
<GridPane.margin>
<Insets left="6.0" top="2.0" />
</GridPane.margin>
<font>
<Font name="System Italic" size="12.0" />
</font>
</Label>
</children>
<GridPane.margin>
<Insets bottom="7.0" left="10.0" right="10.0" top="5.0" />
</GridPane.margin>
</GridPane>
</children>
</GridPane>

Binary file not shown.

View File

@ -1,6 +1,7 @@
package main.protocol; package main.protocol;
import main.OSValidator; import main.OSValidator;
import main.protocol.memory.Rc4Obtainer;
import main.protocol.packethandler.Handler; import main.protocol.packethandler.Handler;
import main.protocol.packethandler.IncomingHandler; import main.protocol.packethandler.IncomingHandler;
import main.protocol.packethandler.OutgoingHandler; import main.protocol.packethandler.OutgoingHandler;
@ -126,10 +127,13 @@ public class HConnection {
final boolean[] aborted = new boolean[1]; final boolean[] aborted = new boolean[1];
Rc4Obtainer rc4Obtainer = new Rc4Obtainer();
// wachten op data van client // wachten op data van client
new Thread(() -> { new Thread(() -> {
try { try {
OutgoingHandler handler = new OutgoingHandler(habbo_server_out); OutgoingHandler handler = new OutgoingHandler(habbo_server_out);
rc4Obtainer.setOutgoingHandler(handler);
while (!client.isClosed() && (state == State.WAITING_FOR_CLIENT || state == State.CONNECTED)) { while (!client.isClosed() && (state == State.WAITING_FOR_CLIENT || state == State.CONNECTED)) {
byte[] buffer; byte[] buffer;
@ -179,6 +183,7 @@ public class HConnection {
new Thread(() -> { new Thread(() -> {
try { try {
IncomingHandler handler = new IncomingHandler(client_out); IncomingHandler handler = new IncomingHandler(client_out);
rc4Obtainer.setIncomingHandler(handler);
while (!habbo_server.isClosed() && (state == State.CONNECTED || state == State.WAITING_FOR_CLIENT)) { while (!habbo_server.isClosed() && (state == State.CONNECTED || state == State.WAITING_FOR_CLIENT)) {
byte[] buffer; byte[] buffer;

View File

@ -21,12 +21,14 @@ public class HPacket {
packetInBytes = fromStringToBytes(fromExpressionToString(packet)); packetInBytes = fromStringToBytes(fromExpressionToString(packet));
} }
public HPacket(int header) { public HPacket(int header) {
packetInBytes = new byte[]{0,0,0,4,0,0}; packetInBytes = new byte[]{0,0,0,2,0,0};
replaceUShort(4, header); replaceUShort(4, header);
isEdited = false;
} }
public HPacket(int header, byte[] bytes) { public HPacket(int header, byte[] bytes) {
packetInBytes = new byte[4]; this(header);
appendBytes(bytes); appendBytes(bytes);
isEdited = false;
} }
public String toString() { public String toString() {

View File

@ -35,6 +35,10 @@ package main.protocol.crypto;
import main.protocol.HPacket; import main.protocol.HPacket;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/** /**
* This is a simple implementation of the RC4 (tm) encryption algorithm. The * This is a simple implementation of the RC4 (tm) encryption algorithm. The
* author implemented this class for some simple applications * author implemented this class for some simple applications
@ -111,6 +115,17 @@ public class RC4 {
} }
public RC4(byte[] state, int x, int y) {
this.x = x;
this.y = y;
this.state = state;
}
//copyconstructor
public RC4 deepCopy() {
return new RC4(Arrays.copyOf(state, 256), x, y);
}
/** /**
* RC4 encryption/decryption. * RC4 encryption/decryption.
* *
@ -169,36 +184,100 @@ public class RC4 {
return result; return result;
} }
public void undoRc4(byte[] buf) {
byte tmp;
for (int i = buf.length - 1; i >= 0; i--) {
tmp = state[x];
state[x] = state[y];
state[y] = tmp;
y = (y - (state[x] & 0xff)) & 0xff;
x = (x - 1) & 0xff;
}
}
public void printKey() { public void printKey() {
System.out.println(new HPacket(state).toString()); System.out.println(new HPacket(state).toString());
} }
private static void printState(byte[] booleans) {
StringBuilder builder = new StringBuilder("state: ");
for (byte bool : booleans) {
builder.append(bool);
builder.append(",");
}
System.out.println(builder);
}
public static void main(String[] args) { public static void main(String[] args) {
byte[] sharedKey = new byte[27]; byte[] sharedKey = new byte[27];
List<Byte> allbytesEncrypted = new ArrayList<>();
RC4 p1 = new RC4(sharedKey); RC4 p1 = new RC4(sharedKey);
RC4 p2 = new RC4(sharedKey);
p1.printKey(); System.out.println("original:");
p2.printKey(); printState(p1.state);
byte[] enc = p1.rc4("hallo".getBytes()); System.out.println("x: " + p1.x + ", y: " + p1.y);
System.out.println(new String(p2.rc4(enc)));
p1.printKey(); byte[] enc1 = p1.rc4("hallo dit istoch wel redelijk veel tekst ofzo denk k".getBytes());
p2.printKey(); for (int i = 0; i < enc1.length; i++) {
allbytesEncrypted.add(enc1[i]);
}
enc = p1.rc4("hallo".getBytes()); byte[] enc2 = p1.rc4("dit is ook redelijk wa tekst maar mag nog veel meer zijn eigelijk in principe hoor".getBytes());
System.out.println(new String(p2.rc4(enc))); for (int i = 0; i < enc2.length; i++) {
allbytesEncrypted.add(enc2[i]);
}
p1.printKey(); System.out.println("-----------");
p2.printKey(); System.out.println("after being sent:");
printState(p1.state);
System.out.println("x: " + p1.x + ", y: " + p1.y);
enc = p1.rc4("meneeeer dit zijn echt veel meer dan 27 characters dus latne we dit even proberen".getBytes());
System.out.println(new String(p2.rc4(enc)));
p1.printKey(); byte[] allencrypted = new byte[allbytesEncrypted.size()];
p2.printKey(); for (int i = 0; i < allbytesEncrypted.size(); i++) {
allencrypted[i] = allbytesEncrypted.get(i);
}
p1.undoRc4(allencrypted);
System.out.println("-----------");
System.out.println("after undo:");
printState(p1.state);
System.out.println("x: " + p1.x + ", y: " + p1.y);
// byte[] sharedKey = new byte[27];
//
// RC4 p1 = new RC4(sharedKey);
// RC4 p2 = new RC4(sharedKey);
//
// p1.printKey();
// p2.printKey();
// byte[] enc = p1.rc4("hallo".getBytes());
// System.out.println(new String(p2.rc4(enc)));
//
// p1.printKey();
// p2.printKey();
//
// enc = p1.rc4("hallo".getBytes());
// System.out.println(new String(p2.rc4(enc)));
//
// p1.printKey();
// p2.printKey();
//
// enc = p1.rc4("meneeeer dit zijn echt veel meer dan 27 characters dus latne we dit even proberen".getBytes());
// System.out.println(new String(p2.rc4(enc)));
//
// p1.printKey();
// p2.printKey();
} }
// public static void main(String[] args) { // public static void main(String[] args) {

View File

@ -4,34 +4,15 @@ import main.irrelevant.Timer;
import java.io.*; import java.io.*;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.util.ArrayList; import java.util.*;
import java.util.Arrays;
import java.util.List;
public class FlashClient { public class FlashClient {
public class MemorySnippet {
long offset;
byte[] data;
public MemorySnippet(long offset, byte[] data) {
this.offset = offset;
this.data = data;
}
public byte[] getData() {
return data;
}
public long getOffset() {
return offset;
}
}
private int PID; private int PID;
private List<long[]> maps; private List<long[]> maps;
private static final boolean DEBUG = false;
public static FlashClient create() { public static FlashClient create() {
File folder = new File("/proc"); File folder = new File("/proc");
FlashClient client = null; FlashClient client = null;
@ -52,7 +33,7 @@ public class FlashClient {
} while (client == null); } while (client == null);
System.out.println("* Found flashclient process: " + client.PID); if (DEBUG) System.out.println("* Found flashclient process: " + client.PID);
return client; return client;
} }
public void refreshMemoryMaps() { public void refreshMemoryMaps() {
@ -85,7 +66,7 @@ public class FlashClient {
e.printStackTrace(); e.printStackTrace();
} }
System.out.println("* Found memory maps (amount: " + maps.size() + ")"); if (DEBUG) System.out.println("* Found memory maps (amount: " + maps.size() + ")");
} }
public List<MemorySnippet> createMemorySnippetList () { public List<MemorySnippet> createMemorySnippetList () {
@ -102,8 +83,12 @@ public class FlashClient {
return result; return result;
} }
public void fetchMemory(List<MemorySnippet> snippets) { public void fetchMemory(List<MemorySnippet> snippets) {
String memoryPath = "/proc/" + PID + "/mem";
for (MemorySnippet snippet : snippets) { for (MemorySnippet snippet : snippets) {
fetchMemory(snippet);
}
}
public void fetchMemory(MemorySnippet snippet) {
String memoryPath = "/proc/" + PID + "/mem";
long begin = snippet.offset; long begin = snippet.offset;
try { try {
RandomAccessFile raf = new RandomAccessFile(memoryPath, "r"); RandomAccessFile raf = new RandomAccessFile(memoryPath, "r");
@ -115,241 +100,57 @@ public class FlashClient {
e.printStackTrace(); e.printStackTrace();
} }
} }
} public List<MemorySnippet> differentiate2(List<MemorySnippet> original, int minChangedBytes, int maxChangedBytes, int range) {
/**
* can remove & add & edit maps of memorysnipperlist
*/
public void updateMapLocationsSnippetList(List<MemorySnippet> snippets) {
refreshMemoryMaps();
List<MemorySnippet> list2 = new ArrayList<>();
List<long[]> not_added = new ArrayList<>();
// readd all maps that stayed the same
for (long[] map : maps) {
//if was in snippetlist:
boolean found = false;
for (MemorySnippet snippet : snippets) {
if (snippet.offset == map[0] && snippet.offset + snippet.getData().length == map[1]) {
list2.add(snippet);
snippets.remove(snippet);
found = true;
break;
}
}
if (!found) {
not_added.add(map);
}
}
for (int i = 0; i < not_added.size(); i++) {
long[] map = not_added.get(i);
//find potential overlap snippet
MemorySnippet snippet = new MemorySnippet(map[0], new byte[(int)(map[1] - map[0])]);
byte[] data = snippet.getData();
for (MemorySnippet potential : snippets) {
//if there is overlap
if ((potential.offset >= map[0] && potential.offset < map[1]) ||
(potential.offset + potential.getData().length >= map[0] && potential.offset + potential.getData().length< map[1]) ||
(potential.offset < map[0] && potential.offset + potential.getData().length >= map[1]) ) {
int start = Math.max((int)(potential.offset - map[0]), 0);
int offset2 = -(int)(potential.offset - map[0]);
for (int j = start; j < Math.min(map[1] - map[0], potential.getData().length - offset2); j++) {
data[j] = potential.getData()[j+offset2];
}
}
}
list2.add(snippet);
}
snippets.clear();
for (MemorySnippet snippet : list2) {
snippets.add(snippet);
}
}
/**
* creates a new memorysnippet list of data that changed (or not) from the original list with a given left&right buffer
*/
public List<MemorySnippet> differentiate(List<MemorySnippet> original, boolean isChanged, int leftRightbytebuffer) {
//fill a new memorysnippet list with live data
List<MemorySnippet> upToDate = new ArrayList<>(); List<MemorySnippet> upToDate = new ArrayList<>();
for (MemorySnippet memorySnippet : original) { for (MemorySnippet memorySnippet : original) {
upToDate.add(new MemorySnippet(memorySnippet.getOffset(), new byte[memorySnippet.getData().length])); upToDate.add(new MemorySnippet(memorySnippet.getOffset(), new byte[memorySnippet.getData().length]));
} }
fetchMemory(upToDate); fetchMemory(upToDate);
List<MemorySnippet> result = new ArrayList<>(); List<MemorySnippet> result = new ArrayList<>();
Queue<Integer> wachter = new LinkedList<>();
long totalBytes = 0;
for (int i = 0; i < original.size(); i++) { for (int i = 0; i < original.size(); i++) {
long offset = original.get(i).getOffset(); wachter.clear();
byte[] old = original.get(i).getData(); int wachtersize = 0;
byte[] curr = upToDate.get(i).getData();
if (!isChanged) { MemorySnippet org = original.get(i);
// find all non-changed stuff and put in result byte[] orgdata = org.getData();
long pre = offset; MemorySnippet upd = upToDate.get(i);
for (int j = 0; j < old.length; j++) { byte[] upddata = upd.getData();
if (old[j] != curr[j]) {
//calculate previous block length int curstartoffset = -1;
int len = j - ((int)(pre - offset)); int lastendbuffer = -1;
if (len >= leftRightbytebuffer && len > 0) {
result.add(new MemorySnippet(pre, new byte[len])); for (int p = 0; p < org.getData().length; p++) {
totalBytes += len; if (wachtersize > 0 && p == wachter.peek()) {
wachter.poll();
wachtersize--;
} }
pre = offset + j + 1; if (orgdata[p] != upddata[p]) {
wachter.add(p + range);
wachtersize++;
}
if (p >= range - 1 && wachtersize >= minChangedBytes && wachtersize <= maxChangedBytes) {
if (curstartoffset == -1) {
curstartoffset = p - range + 1;
}
else if (lastendbuffer < p - range) {
MemorySnippet snippet = new MemorySnippet(curstartoffset + org.getOffset(), new byte[lastendbuffer - curstartoffset + 1]);
result.add(snippet);
curstartoffset = p - range + 1;
}
lastendbuffer = p;
} }
} }
int len = old.length - ((int)(pre - offset)); if (curstartoffset != -1) {
if (len >= leftRightbytebuffer && len > 0) { MemorySnippet snippet = new MemorySnippet(curstartoffset + org.getOffset(), new byte[lastendbuffer - curstartoffset + 1]);
result.add(new MemorySnippet(pre, new byte[len])); result.add(snippet);
totalBytes += len;
}
}
else {
//find all changed stuff and put result
long pre = offset;
int downCount = -1; //if downCount reaches zero, buffer should be written out
for (int j = 0; j < old.length; j++) {
if (old[j] != curr[j]) {
if (downCount <= 0) {
pre = Math.max(offset, offset + j - leftRightbytebuffer);
}
downCount = leftRightbytebuffer;
}
else { downCount -= 1; }
if (downCount == 0) {
int len = j - ((int)(pre - offset));
result.add(new MemorySnippet(pre, new byte[len]));
totalBytes += len;
}
}
int len = old.length - ((int)(pre - offset));
if (downCount > 0 && len >= leftRightbytebuffer) {
result.add(new MemorySnippet(pre, new byte[len]));
totalBytes += len;
}
} }
} }
fetchMemory(result); fetchMemory(result);
System.out.println("totalbytes after diff: " + totalBytes);
return result; return result;
} }
//currently not being used functions:
List<Long> searchOffsetForByteArray(byte[] toFind) {
if (toFind.length == 0) return null;
System.out.println("*** Start searching for: " + new String(toFind));
String memoryPath = "/proc/" + PID + "/mem";
List<Long> results = new ArrayList<>();
Timer t = new Timer();
t.start();
for (long[] map : maps) {
long begin = map[0];
long end = map[1];
try {
RandomAccessFile raf = new RandomAccessFile(memoryPath, "r");
byte[] wholeBuffer = new byte[(int)(end - begin)];
raf.seek(begin);
raf.read(wholeBuffer);
raf.close();
for (int i = 0; i < wholeBuffer.length; i++) {
int subIndex = 0;
while (subIndex < toFind.length && wholeBuffer[i + subIndex] == toFind[subIndex]) subIndex++;
if (subIndex == toFind.length) {
long result = (long)i + begin;
results.add(result);
System.out.println("* Found match for " + new String(toFind) + " at address: " + result);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
System.out.println("*** End searching for: " + new String(toFind) + " in " + t.delta() + "ms");
return results;
}
List<Long> searchOffsetForString(String keyString) {
return searchOffsetForByteArray(keyString.getBytes());
}
public List<String> findSharedKey (List<MemorySnippet> snippets){
byte[] bounds = "09afAF".getBytes();
List<String> results = new ArrayList<>();
int size = 54;
for (MemorySnippet snippet : snippets) {
int count = 0;
byte[] data = snippet.getData();
if (data.length >= size) {
for (int i = 0; i < data.length; i++) {
byte b = data[i];
if ((b >= bounds[0] && b <= bounds[1]) ||
(b >= bounds[2] && b <= bounds[3]) ||
(b >= bounds[4] && b <= bounds[5])) {
count++;
}
else {
count = 0;
}
if (count == size && (i + 1 == data.length || !((data[i+1] >= bounds[0] && data[i+1] <= bounds[1]) ||
(data[i+1] >= bounds[2] && data[i+1] <= bounds[3]) ||
(data[i+1] >= bounds[4] && data[i+1] <= bounds[5]))) ) {
results.add(new String(Arrays.copyOfRange(data, i - size + 1, i + 1)) + " on location: " + (snippet.getOffset() + i));
}
}
}
}
return results;
}
public List<String> findSharedKey2() {
List<MemorySnippet> memorySnippets = new ArrayList<>();
int buff = 15000000;
long verystart = maps.get(0)[0];
long veryend = maps.get(0)[1];
for (int i = 1; i < maps.size(); i++) {
long[] map = maps.get(i);
if (map[1] - veryend <= buff) {
veryend = map[1];
}
else {
memorySnippets.add(new MemorySnippet(verystart, new byte[(int)(veryend - verystart + buff)]));
verystart = maps.get(i)[0];
veryend = maps.get(i)[1];
}
}
memorySnippets.add(new MemorySnippet(verystart, new byte[(int)(veryend - verystart + buff)]));
fetchMemory(memorySnippets);
return findSharedKey(memorySnippets);
}
@SuppressWarnings("Duplicates") @SuppressWarnings("Duplicates")
public void pauseProcess() { public void pauseProcess() {
String[] args = new String[] {"kill", "-STOP", PID+""}; String[] args = new String[] {"kill", "-STOP", PID+""};
@ -401,10 +202,8 @@ public class FlashClient {
// client.updateMapLocationsSnippetList(l); // client.updateMapLocationsSnippetList(l);
List<String> res = client.findSharedKey2();
System.out.println(res);
System.out.println("test");
} }
} }

View File

@ -0,0 +1,19 @@
package main.protocol.memory;
public class MemorySnippet {
long offset;
byte[] data;
public MemorySnippet(long offset, byte[] data) {
this.offset = offset;
this.data = data;
}
public byte[] getData() {
return data;
}
public long getOffset() {
return offset;
}
}

View File

@ -2,33 +2,34 @@ package main.protocol.memory;
import javafx.application.Platform; import javafx.application.Platform;
import main.protocol.HPacket; import main.protocol.HPacket;
import main.protocol.crypto.RC4;
import main.protocol.packethandler.BufferListener; import main.protocol.packethandler.BufferListener;
import main.protocol.packethandler.IncomingHandler; import main.protocol.packethandler.IncomingHandler;
import main.protocol.packethandler.OutgoingHandler; import main.protocol.packethandler.OutgoingHandler;
import main.protocol.memory.FlashClient; import main.protocol.memory.FlashClient;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Random;
public class Rc4Obtainer { public class Rc4Obtainer {
public static Rc4Obtainer rc4Obtainer = null; public static final boolean DEBUG = false;
public static void initialize() {
rc4Obtainer = new Rc4Obtainer();
rc4Obtainer.client = FlashClient.create();
}
FlashClient client = null; FlashClient client = null;
OutgoingHandler outgoingHandler = null; OutgoingHandler outgoingHandler = null;
IncomingHandler incomingHandler = null; IncomingHandler incomingHandler = null;
private Rc4Obtainer() { public Rc4Obtainer() {
client = FlashClient.create();
} }
private boolean hashappened1 = false;
public void setOutgoingHandler(OutgoingHandler handler) { public void setOutgoingHandler(OutgoingHandler handler) {
outgoingHandler = handler; outgoingHandler = handler;
handler.addBufferListener(() -> { handler.addBufferListener((int addedbytes) -> {
if (handler.getCurrentIndex() >= 3) hasChangedFromLastCheck = true; if (handler.getCurrentIndex() >= 3) this.addedBytes += addedbytes;
if (!hashappened1 && handler.getCurrentIndex() == 3) { if (!hashappened1 && handler.getCurrentIndex() == 3) {
hashappened1 = true; hashappened1 = true;
onSendFirstEncryptedMessage(); onSendFirstEncryptedMessage();
@ -38,91 +39,182 @@ public class Rc4Obtainer {
public void setIncomingHandler(IncomingHandler handler) { public void setIncomingHandler(IncomingHandler handler) {
incomingHandler = handler; incomingHandler = handler;
handler.addBufferListener(() -> {
if (!hashappened2 && handler.getCurrentIndex() == 1) {
hashappened2 = true;
onReceivePubKey();
}
});
} }
private List<FlashClient.MemorySnippet> fullmemorybeforekey = null; private volatile int addedBytes = 0;
private boolean hasChangedFromLastCheck = false;
private boolean hashappened2 = false;
private void onReceivePubKey() {
incomingHandler.block();
new Thread(() -> {
System.out.println("[+] receive pubkey");
client.pauseProcess();
fullmemorybeforekey = client.createMemorySnippetList();
client.fetchMemory(fullmemorybeforekey);
System.out.println("[-] receive pubkey");
client.resumeProcess();
incomingHandler.unblock();
}).start();
}
private boolean hashappened1 = false;
private void onSendFirstEncryptedMessage() { private void onSendFirstEncryptedMessage() {
incomingHandler.block(); incomingHandler.block();
outgoingHandler.block(); outgoingHandler.block();
new Thread(() -> { new Thread(() -> {
System.out.println("[+] send encrypted"); if (DEBUG) System.out.println("[+] send encrypted");
client.pauseProcess(); sleep(20);
client.updateMapLocationsSnippetList(fullmemorybeforekey);
client.resumeProcess();
List<FlashClient.MemorySnippet> diff = searchForPossibleRC4Tables(fullmemorybeforekey); List<MemorySnippet> diff = null;
System.out.println("size: " + getTotalBytesLengthOfDiff(diff));
for (int i = 0; i < 20; i++) {
// if (i % 2 == 1) { // STEP ONE: filtering to obtain one area containing the rc4 data field
// incomingHandler.sendToStream(new HPacket(3631).toBytes()); int foundbuffersize = 0;
// } while (foundbuffersize == 0) {
sleep(200); client.pauseProcess();
boolean rem = hasChangedFromLastCheck; diff = client.createMemorySnippetList();
client.fetchMemory(diff);
client.resumeProcess();
this.addedBytes = 0;
Random rand = new Random();
if (DEBUG) System.out.println("size: " + getTotalBytesLengthOfDiff(diff));
int i = 0;
while (getTotalBytesLengthOfDiff(diff) > 2000) {
int am = 0;
if (i % 2 == 1) {
am = rand.nextInt(30) + 1;
for (int j = 0; j < am; j++) {
incomingHandler.sendToStream(new HPacket(3794).toBytes());
outgoingHandler.fakePongAlert();
sleep(20);
}
}
sleep(50);
int rem = addedBytes;
diff = searchForPossibleRC4Tables(diff); diff = searchForPossibleRC4Tables(diff);
System.out.println("size: " + getTotalBytesLengthOfDiff(diff) + " and was changed: " + rem); if (DEBUG) System.out.println("size: " + getTotalBytesLengthOfDiff(diff) + " with changed bytes: " + rem + " should be: " + am * 6);
i++;
}
foundbuffersize = (int)getTotalBytesLengthOfDiff(diff);
} }
System.out.println("[-] send encrypted");
//diff should only have one element now
// STEP TWO: obtain the exactly the 256 needed bytes
//research shows that this equals the first occurence of a number followed by 3 zeros is the start
//if that number accidentally is zero it won't work so fuck that - cry -
MemorySnippet snippet = diff.get(0);
byte[] wannabeRC4data = snippet.getData();
int result_start_index = -1;
for (int i = 0; i < snippet.getData().length - 3; i++) {
if (wannabeRC4data[i] != 0 && wannabeRC4data[i+1] == 0 && wannabeRC4data[i+2] == 0 && wannabeRC4data[i+3] == 0) {
result_start_index = i;
if (DEBUG) System.out.println(result_start_index);
break;
}
}
byte[] data = new byte[256]; // dis is the friggin key
for (int i = 0; i < 256; i++) data[i] = wannabeRC4data[i*4 + result_start_index];
if (DEBUG) printByteArray(data);
// STEP 3: find the i & j values (in our RC4 class called x & y)
// this goes together with the verification of this actually being the right RC4 table
MemorySnippet snippet1 = new MemorySnippet(snippet.getOffset(), new byte[snippet.getData().length]);
client.fetchMemory(snippet1);
incomingHandler.sendToStream(new HPacket(3794).toBytes());
outgoingHandler.fakePongAlert();
sleep(70);
byte[] data1 = new byte[256];
for (int i = 0; i < 256; i++) data1[i] = snippet1.getData()[i*4 + result_start_index];
byte[] lastPongPacket = new byte[6];
List<Byte> encodedbytelistraw = outgoingHandler.getEncryptedBuffer();
for (int i = 0; i < 6; i++) {
lastPongPacket[i] = encodedbytelistraw.get(encodedbytelistraw.size() - 6 + i);
}
RC4 result = null;
//dont panic this runs extremely fast xo
outerloop:
for (int x = 0; x < 256; x++) {
for (int y = 0; y < 256; y++) {
byte[] copy = new byte[256];
for (int i = 0; i < 256; i++) {
copy[i] = data1[i];
}
RC4 rc4Tryout = new RC4(copy, x, y);
HPacket tryout = new HPacket(rc4Tryout.rc4(lastPongPacket));
if (!tryout.isCorrupted()) {
result = rc4Tryout;
break outerloop;
}
}
}
// STEP FOUR: undo all sent packets in the rc4 stream
List<Byte> enbuf = outgoingHandler.getEncryptedBuffer();
byte[] encrbuffer = new byte[enbuf.size()];
for (int i = 0; i < enbuf.size(); i++) {
encrbuffer[i] = enbuf.get(i);
}
result.undoRc4(encrbuffer);
// STEP FIVE: set the rc4 stream
if (result != null) {
outgoingHandler.setRc4(result);
}
else {
System.err.println("Did not find RC4 stream");
}
if (DEBUG) System.out.println("[-] send encrypted");
outgoingHandler.unblock(); outgoingHandler.unblock();
incomingHandler.unblock(); incomingHandler.unblock();
}).start(); }).start();
} }
private List<FlashClient.MemorySnippet> searchForPossibleRC4Tables(List<FlashClient.MemorySnippet> snippets) {
List<FlashClient.MemorySnippet> result;
private List<MemorySnippet> searchForPossibleRC4Tables(List<MemorySnippet> snippets) {
List<MemorySnippet> result;
client.pauseProcess(); client.pauseProcess();
if (hasChangedFromLastCheck) { result = client.differentiate2(snippets, ((addedBytes * 2) / 3), addedBytes * 2, 1028);
result = client.differentiate(snippets, true, 255); addedBytes = 0;
hasChangedFromLastCheck = false;
}
else {
result = client.differentiate(snippets, false, 4);
}
client.resumeProcess(); client.resumeProcess();
return result; return result;
} }
private long getTotalBytesLengthOfDiff(List<FlashClient.MemorySnippet> snippets) { private void printBooleanArray(boolean[] booleans) {
StringBuilder builder = new StringBuilder();
for (boolean bool : booleans) {
builder.append(bool ? "1" : "0");
}
System.out.println(builder);
}
private void printByteArray(byte[] booleans) {
StringBuilder builder = new StringBuilder();
for (byte bool : booleans) {
builder.append(bool);
builder.append(",");
}
System.out.println(builder);
}
private long getTotalBytesLengthOfDiff(List<MemorySnippet> snippets) {
long tot = 0; long tot = 0;
for (FlashClient.MemorySnippet snippet : snippets) { for (MemorySnippet snippet : snippets) {
tot += (snippet.getData().length); tot += (snippet.getData().length);
} }
return tot; return tot;
} }
private void sleep(int ms) { private void sleep(int ms) {
try { try {
Thread.sleep(ms); Thread.sleep(ms);

View File

@ -3,6 +3,6 @@ package main.protocol.packethandler;
public interface BufferListener { public interface BufferListener {
void act(); void act(int addedbytes);
} }

View File

@ -12,8 +12,8 @@ public abstract class Handler {
volatile PayloadBuffer payloadBuffer = new PayloadBuffer(); volatile PayloadBuffer payloadBuffer = new PayloadBuffer();
volatile OutputStream out; volatile OutputStream out;
private volatile Object[] listeners = null; //get notified on packet send volatile Object[] listeners = null; //get notified on packet send
private volatile boolean isTempBlocked = false; volatile boolean isTempBlocked = false;
volatile boolean isDataStream = false; volatile boolean isDataStream = false;
volatile int currentIndex = 0; volatile int currentIndex = 0;
@ -32,16 +32,11 @@ public abstract class Handler {
if (isDataStream) { if (isDataStream) {
payloadBuffer.push(buffer); payloadBuffer.push(buffer);
notifyBufferListeners(); notifyBufferListeners(buffer.length);
if (!isTempBlocked) { if (!isTempBlocked) {
flush(); flush();
} }
else {
if (this instanceof OutgoingHandler) {
System.out.println("blocked outgoing bytes with size: "+ buffer.length);
}
}
} }
else { else {
out.write(buffer); out.write(buffer);
@ -88,9 +83,9 @@ public abstract class Handler {
public void removeBufferListener(BufferListener listener) { public void removeBufferListener(BufferListener listener) {
bufferListeners.remove(listener); bufferListeners.remove(listener);
} }
private void notifyBufferListeners() { void notifyBufferListeners(int addedbytes) {
for (int i = bufferListeners.size() - 1; i >= 0; i -= 1) { for (int i = bufferListeners.size() - 1; i >= 0; i -= 1) {
bufferListeners.get(i).act(); bufferListeners.get(i).act(addedbytes);
} }
} }

View File

@ -13,14 +13,11 @@ public class IncomingHandler extends Handler {
super(outputStream); super(outputStream);
} }
@Override private final Object lock = new Object();
public void setAsDataStream() {
super.setAsDataStream();
Rc4Obtainer.rc4Obtainer.setIncomingHandler(this);
}
@Override @Override
public void sendToStream(byte[] buffer) { public void sendToStream(byte[] buffer) {
synchronized (lock) {
try { try {
out.write(buffer); out.write(buffer);
out.flush(); out.flush();
@ -28,9 +25,11 @@ public class IncomingHandler extends Handler {
e.printStackTrace(); e.printStackTrace();
} }
} }
}
@Override @Override
public void flush() throws IOException { public void flush() throws IOException {
synchronized (lock) {
HPacket[] hpackets = payloadBuffer.receive(); HPacket[] hpackets = payloadBuffer.receive();
for (HPacket hpacket : hpackets){ for (HPacket hpacket : hpackets){
@ -43,4 +42,6 @@ public class IncomingHandler extends Handler {
currentIndex++; currentIndex++;
} }
} }
}
} }

View File

@ -2,14 +2,23 @@ package main.protocol.packethandler;
import main.protocol.HMessage; import main.protocol.HMessage;
import main.protocol.HPacket; import main.protocol.HPacket;
import main.protocol.crypto.RC4;
import main.protocol.memory.Rc4Obtainer; import main.protocol.memory.Rc4Obtainer;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
public class OutgoingHandler extends Handler { public class OutgoingHandler extends Handler {
private final Object lock = new Object();
private final static int encryptOffset = 3; //all packets with index < 3 aren't encrypted private final static int encryptOffset = 3; //all packets with index < 3 aren't encrypted
private RC4 clientcipher = null;
private RC4 servercipher = null;
private List<Byte> tempEncryptedBuffer = new ArrayList<>();
public OutgoingHandler(OutputStream outputStream) { public OutgoingHandler(OutputStream outputStream) {
super(outputStream); super(outputStream);
@ -19,49 +28,101 @@ public class OutgoingHandler extends Handler {
if (!isDataStream) { if (!isDataStream) {
HPacket hpacket = new HPacket(buffer); HPacket hpacket = new HPacket(buffer);
isDataStream = (hpacket.getBytesLength() > 6 && hpacket.headerId() == 4000 && hpacket.headerId() == 4000); isDataStream = (hpacket.getBytesLength() > 6 && hpacket.headerId() == 4000 && hpacket.headerId() == 4000);
if (isDataStream) {
Rc4Obtainer.initialize();
Rc4Obtainer.rc4Obtainer.setOutgoingHandler(this);
}
} }
} }
@Override @Override
public void act(byte[] buffer, Object[] listeners) throws IOException { public void act(byte[] buffer, Object[] listeners) throws IOException {
dataStreamCheck(buffer); dataStreamCheck(buffer);
super.act(buffer, listeners); this.listeners = listeners;
if (isDataStream) {
if (currentIndex < encryptOffset) {
payloadBuffer.push(buffer);
}
else if (clientcipher == null) {
for (int i = 0; i < buffer.length; i++) {
tempEncryptedBuffer.add(buffer[i]);
}
}
else {
payloadBuffer.push(clientcipher.rc4(buffer));
}
notifyBufferListeners(buffer.length);
if (!isTempBlocked) {
flush();
}
}
else {
out.write(buffer);
}
} }
@Override @Override
public void sendToStream(byte[] buffer) { public void sendToStream(byte[] buffer) {
synchronized (lock) {
try {
out.write(servercipher.rc4(buffer));
out.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
} }
public void setRc4(RC4 rc4) {
this.clientcipher = rc4;
this.servercipher = rc4.deepCopy();
byte[] encrbuffer = new byte[tempEncryptedBuffer.size()];
for (int i = 0; i < tempEncryptedBuffer.size(); i++) {
encrbuffer[i] = tempEncryptedBuffer.get(i);
}
try {
act(encrbuffer, this.listeners);
} catch (IOException e) {
e.printStackTrace();
}
tempEncryptedBuffer = null;
}
public List<Byte> getEncryptedBuffer() {
return tempEncryptedBuffer;
}
//as pings & pongs are used in order to find the RC4 table, we really don't want it to be displayed
//or even be sent to the server, we can fix that by calling this method everytime we fakesend a ping
private int skipPongAmount = 0;
public void fakePongAlert() {
skipPongAmount ++;
}
@Override @Override
public void flush() throws IOException { public void flush() throws IOException {
synchronized (lock) {
if (currentIndex < encryptOffset) {
HPacket[] hpackets = payloadBuffer.receive(); HPacket[] hpackets = payloadBuffer.receive();
for (HPacket hpacket : hpackets){ for (HPacket hpacket : hpackets){
if (skipPongAmount > 0 && hpacket.length() == 2) {
skipPongAmount --;
continue;
}
HMessage hMessage = new HMessage(hpacket, HMessage.Side.TOSERVER, currentIndex); HMessage hMessage = new HMessage(hpacket, HMessage.Side.TOSERVER, currentIndex);
notifyListeners(hMessage); notifyListeners(hMessage);
if (!hMessage.isBlocked()) { if (!hMessage.isBlocked()) {
out.write(hMessage.getPacket().toBytes()); out.write(
currentIndex < encryptOffset ? hMessage.getPacket().toBytes() :
servercipher.rc4(hMessage.getPacket().toBytes())
);
} }
currentIndex ++; currentIndex ++;
} }
} }
if (currentIndex >= encryptOffset) {
if (payloadBuffer.peak().length > 0) {
HPacket packet = new HPacket(payloadBuffer.forceClear());
HMessage hMessage = new HMessage(packet, HMessage.Side.TOSERVER, currentIndex);
notifyListeners(hMessage);
out.write(packet.toBytes());
currentIndex++;
}
}
} }
} }