();
36 | cachedGenerators.Add(new GenericGFPoly(field, new int[] { 1 }));
37 | }
38 |
39 | private GenericGFPoly buildGenerator(int degree)
40 | {
41 | if (degree >= cachedGenerators.Count)
42 | {
43 | var lastGenerator = cachedGenerators[cachedGenerators.Count - 1];
44 | for (int d = cachedGenerators.Count; d <= degree; d++)
45 | {
46 | var nextGenerator = lastGenerator.multiply(new GenericGFPoly(field, new int[] { 1, field.exp(d - 1 + field.GeneratorBase) }));
47 | cachedGenerators.Add(nextGenerator);
48 | lastGenerator = nextGenerator;
49 | }
50 | }
51 | return cachedGenerators[degree];
52 | }
53 |
54 | public void encode(int[] toEncode, int ecBytes)
55 | {
56 | if (ecBytes == 0)
57 | {
58 | throw new ArgumentException("No error correction bytes");
59 | }
60 | var dataBytes = toEncode.Length - ecBytes;
61 | if (dataBytes <= 0)
62 | {
63 | throw new ArgumentException("No data bytes provided");
64 | }
65 |
66 | var generator = buildGenerator(ecBytes);
67 | var infoCoefficients = new int[dataBytes];
68 | Array.Copy(toEncode, 0, infoCoefficients, 0, dataBytes);
69 |
70 | var info = new GenericGFPoly(field, infoCoefficients);
71 | info = info.multiplyByMonomial(ecBytes, 1);
72 |
73 | var remainder = info.divide(generator)[1];
74 | var coefficients = remainder.Coefficients;
75 | var numZeroCoefficients = ecBytes - coefficients.Length;
76 | for (var i = 0; i < numZeroCoefficients; i++)
77 | {
78 | toEncode[dataBytes + i] = 0;
79 | }
80 |
81 | Array.Copy(coefficients, 0, toEncode, dataBytes + numZeroCoefficients, coefficients.Length);
82 | }
83 | }
84 | }
--------------------------------------------------------------------------------
/shadowsocks-csharp/3rd/zxing/qrcode/decoder/DataBlock.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2007 ZXing authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | namespace ZXing.QrCode.Internal
18 | {
19 | /// Encapsulates a block of data within a QR Code. QR Codes may split their data into
20 | /// multiple blocks, each of which is a unit of data and error-correction codewords. Each
21 | /// is represented by an instance of this class.
22 | ///
23 | ///
24 | /// Sean Owen
25 | ///
26 | /// www.Redivivus.in (suraj.supekar@redivivus.in) - Ported from ZXING Java Source
27 | ///
28 | internal sealed class DataBlock
29 | {
30 | private readonly int numDataCodewords;
31 | private readonly byte[] codewords;
32 |
33 | private DataBlock(int numDataCodewords, byte[] codewords)
34 | {
35 | this.numDataCodewords = numDataCodewords;
36 | this.codewords = codewords;
37 | }
38 |
39 | /// When QR Codes use multiple data blocks, they are actually interleaved.
40 | /// That is, the first byte of data block 1 to n is written, then the second bytes, and so on. This
41 | /// method will separate the data into original blocks.
42 | ///
43 | ///
44 | /// bytes as read directly from the QR Code
45 | ///
46 | /// version of the QR Code
47 | ///
48 | /// error-correction level of the QR Code
49 | ///
50 | /// {@link DataBlock}s containing original bytes, "de-interleaved" from representation in the
51 | /// QR Code
52 | ///
53 | internal static DataBlock[] getDataBlocks(byte[] rawCodewords, Version version, ErrorCorrectionLevel ecLevel)
54 | {
55 |
56 | if (rawCodewords.Length != version.TotalCodewords)
57 | {
58 | throw new System.ArgumentException();
59 | }
60 |
61 | // Figure out the number and size of data blocks used by this version and
62 | // error correction level
63 | Version.ECBlocks ecBlocks = version.getECBlocksForLevel(ecLevel);
64 |
65 | // First count the total number of data blocks
66 | int totalBlocks = 0;
67 | Version.ECB[] ecBlockArray = ecBlocks.getECBlocks();
68 | foreach (var ecBlock in ecBlockArray)
69 | {
70 | totalBlocks += ecBlock.Count;
71 | }
72 |
73 | // Now establish DataBlocks of the appropriate size and number of data codewords
74 | DataBlock[] result = new DataBlock[totalBlocks];
75 | int numResultBlocks = 0;
76 | foreach (var ecBlock in ecBlockArray)
77 | {
78 | for (int i = 0; i < ecBlock.Count; i++)
79 | {
80 | int numDataCodewords = ecBlock.DataCodewords;
81 | int numBlockCodewords = ecBlocks.ECCodewordsPerBlock + numDataCodewords;
82 | result[numResultBlocks++] = new DataBlock(numDataCodewords, new byte[numBlockCodewords]);
83 | }
84 | }
85 |
86 | // All blocks have the same amount of data, except that the last n
87 | // (where n may be 0) have 1 more byte. Figure out where these start.
88 | int shorterBlocksTotalCodewords = result[0].codewords.Length;
89 | int longerBlocksStartAt = result.Length - 1;
90 | while (longerBlocksStartAt >= 0)
91 | {
92 | int numCodewords = result[longerBlocksStartAt].codewords.Length;
93 | if (numCodewords == shorterBlocksTotalCodewords)
94 | {
95 | break;
96 | }
97 | longerBlocksStartAt--;
98 | }
99 | longerBlocksStartAt++;
100 |
101 | int shorterBlocksNumDataCodewords = shorterBlocksTotalCodewords - ecBlocks.ECCodewordsPerBlock;
102 | // The last elements of result may be 1 element longer;
103 | // first fill out as many elements as all of them have
104 | int rawCodewordsOffset = 0;
105 | for (int i = 0; i < shorterBlocksNumDataCodewords; i++)
106 | {
107 | for (int j = 0; j < numResultBlocks; j++)
108 | {
109 | result[j].codewords[i] = rawCodewords[rawCodewordsOffset++];
110 | }
111 | }
112 | // Fill out the last data block in the longer ones
113 | for (int j = longerBlocksStartAt; j < numResultBlocks; j++)
114 | {
115 | result[j].codewords[shorterBlocksNumDataCodewords] = rawCodewords[rawCodewordsOffset++];
116 | }
117 | // Now add in error correction blocks
118 | int max = result[0].codewords.Length;
119 | for (int i = shorterBlocksNumDataCodewords; i < max; i++)
120 | {
121 | for (int j = 0; j < numResultBlocks; j++)
122 | {
123 | int iOffset = j < longerBlocksStartAt ? i : i + 1;
124 | result[j].codewords[iOffset] = rawCodewords[rawCodewordsOffset++];
125 | }
126 | }
127 | return result;
128 | }
129 |
130 | internal int NumDataCodewords
131 | {
132 | get
133 | {
134 | return numDataCodewords;
135 | }
136 | }
137 |
138 | internal byte[] Codewords
139 | {
140 | get
141 | {
142 | return codewords;
143 | }
144 | }
145 | }
146 | }
--------------------------------------------------------------------------------
/shadowsocks-csharp/3rd/zxing/qrcode/decoder/DataMask.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2007 ZXing authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | using ZXing.Common;
18 |
19 | namespace ZXing.QrCode.Internal
20 | {
21 | /// Encapsulates data masks for the data bits in a QR code, per ISO 18004:2006 6.8. Implementations
22 | /// of this class can un-mask a raw BitMatrix. For simplicity, they will unmask the entire BitMatrix,
23 | /// including areas used for finder patterns, timing patterns, etc. These areas should be unused
24 | /// after the point they are unmasked anyway.
25 | ///
26 | /// Note that the diagram in section 6.8.1 is misleading since it indicates that i is column position
27 | /// and j is row position. In fact, as the text says, i is row position and j is column position.
28 | ///
29 | ///
30 | /// Sean Owen
31 | ///
32 | /// www.Redivivus.in (suraj.supekar@redivivus.in) - Ported from ZXING Java Source
33 | ///
34 | abstract class DataMask
35 | {
36 | /// See ISO 18004:2006 6.8.1
37 | private static readonly DataMask[] DATA_MASKS = new DataMask[]
38 | {
39 | new DataMask000(),
40 | new DataMask001(),
41 | new DataMask010(),
42 | new DataMask011(),
43 | new DataMask100(),
44 | new DataMask101(),
45 | new DataMask110(),
46 | new DataMask111()
47 | };
48 |
49 | private DataMask()
50 | {
51 | }
52 |
53 | /// Implementations of this method reverse the data masking process applied to a QR Code and
54 | /// make its bits ready to read.
55 | ///
56 | ///
57 | /// representation of QR Code bits
58 | ///
59 | /// dimension of QR Code, represented by bits, being unmasked
60 | ///
61 | internal void unmaskBitMatrix(BitMatrix bits, int dimension)
62 | {
63 | for (int i = 0; i < dimension; i++)
64 | {
65 | for (int j = 0; j < dimension; j++)
66 | {
67 | if (isMasked(i, j))
68 | {
69 | bits.flip(j, i);
70 | }
71 | }
72 | }
73 | }
74 |
75 | internal abstract bool isMasked(int i, int j);
76 |
77 | /// a value between 0 and 7 indicating one of the eight possible
78 | /// data mask patterns a QR Code may use
79 | ///
80 | /// {@link DataMask} encapsulating the data mask pattern
81 | ///
82 | internal static DataMask forReference(int reference)
83 | {
84 | if (reference < 0 || reference > 7)
85 | {
86 | throw new System.ArgumentException();
87 | }
88 | return DATA_MASKS[reference];
89 | }
90 |
91 | /// 000: mask bits for which (x + y) mod 2 == 0
92 | private sealed class DataMask000 : DataMask
93 | {
94 | internal override bool isMasked(int i, int j)
95 | {
96 | return ((i + j) & 0x01) == 0;
97 | }
98 | }
99 |
100 | /// 001: mask bits for which x mod 2 == 0
101 | private sealed class DataMask001 : DataMask
102 | {
103 | internal override bool isMasked(int i, int j)
104 | {
105 | return (i & 0x01) == 0;
106 | }
107 | }
108 |
109 | /// 010: mask bits for which y mod 3 == 0
110 | private sealed class DataMask010 : DataMask
111 | {
112 | internal override bool isMasked(int i, int j)
113 | {
114 | return j % 3 == 0;
115 | }
116 | }
117 |
118 | /// 011: mask bits for which (x + y) mod 3 == 0
119 | private sealed class DataMask011 : DataMask
120 | {
121 | internal override bool isMasked(int i, int j)
122 | {
123 | return (i + j) % 3 == 0;
124 | }
125 | }
126 |
127 | /// 100: mask bits for which (x/2 + y/3) mod 2 == 0
128 | private sealed class DataMask100 : DataMask
129 | {
130 | internal override bool isMasked(int i, int j)
131 | {
132 | return ((((int)((uint)i >> 1)) + (j / 3)) & 0x01) == 0;
133 | }
134 | }
135 |
136 | /// 101: mask bits for which xy mod 2 + xy mod 3 == 0
137 | private sealed class DataMask101 : DataMask
138 | {
139 | internal override bool isMasked(int i, int j)
140 | {
141 | int temp = i * j;
142 | return (temp & 0x01) + (temp % 3) == 0;
143 | }
144 | }
145 |
146 | /// 110: mask bits for which (xy mod 2 + xy mod 3) mod 2 == 0
147 | private sealed class DataMask110 : DataMask
148 | {
149 | internal override bool isMasked(int i, int j)
150 | {
151 | int temp = i * j;
152 | return (((temp & 0x01) + (temp % 3)) & 0x01) == 0;
153 | }
154 | }
155 |
156 | /// 111: mask bits for which ((x+y)mod 2 + xy mod 3) mod 2 == 0
157 | private sealed class DataMask111 : DataMask
158 | {
159 | internal override bool isMasked(int i, int j)
160 | {
161 | return ((((i + j) & 0x01) + ((i * j) % 3)) & 0x01) == 0;
162 | }
163 | }
164 | }
165 | }
--------------------------------------------------------------------------------
/shadowsocks-csharp/3rd/zxing/qrcode/decoder/ErrorCorrectionLevel.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2007 ZXing authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | using System;
18 |
19 | namespace ZXing.QrCode.Internal
20 | {
21 | ///
22 | /// See ISO 18004:2006, 6.5.1. This enum encapsulates the four error correction levels
23 | /// defined by the QR code standard.
24 | ///
25 | /// Sean Owen
26 | public sealed class ErrorCorrectionLevel
27 | {
28 | /// L = ~7% correction
29 | public static readonly ErrorCorrectionLevel L = new ErrorCorrectionLevel(0, 0x01, "L");
30 | /// M = ~15% correction
31 | public static readonly ErrorCorrectionLevel M = new ErrorCorrectionLevel(1, 0x00, "M");
32 | /// Q = ~25% correction
33 | public static readonly ErrorCorrectionLevel Q = new ErrorCorrectionLevel(2, 0x03, "Q");
34 | /// H = ~30% correction
35 | public static readonly ErrorCorrectionLevel H = new ErrorCorrectionLevel(3, 0x02, "H");
36 |
37 | private static readonly ErrorCorrectionLevel[] FOR_BITS = new [] { M, L, H, Q };
38 |
39 | private readonly int bits;
40 |
41 | private ErrorCorrectionLevel(int ordinal, int bits, String name)
42 | {
43 | this.ordinal_Renamed_Field = ordinal;
44 | this.bits = bits;
45 | this.name = name;
46 | }
47 |
48 | ///
49 | /// Gets the bits.
50 | ///
51 | public int Bits
52 | {
53 | get
54 | {
55 | return bits;
56 | }
57 | }
58 |
59 | ///
60 | /// Gets the name.
61 | ///
62 | public String Name
63 | {
64 | get
65 | {
66 | return name;
67 | }
68 | }
69 |
70 | private readonly int ordinal_Renamed_Field;
71 | private readonly String name;
72 |
73 | ///
74 | /// Ordinals this instance.
75 | ///
76 | ///
77 | public int ordinal()
78 | {
79 | return ordinal_Renamed_Field;
80 | }
81 |
82 | ///
83 | /// Returns a that represents this instance.
84 | ///
85 | ///
86 | /// A that represents this instance.
87 | ///
88 | public override String ToString()
89 | {
90 | return name;
91 | }
92 |
93 | ///
94 | /// Fors the bits.
95 | ///
96 | /// int containing the two bits encoding a QR Code's error correction level
97 | ///
98 | /// representing the encoded error correction level
99 | ///
100 | public static ErrorCorrectionLevel forBits(int bits)
101 | {
102 | if (bits < 0 || bits >= FOR_BITS.Length)
103 | {
104 | throw new ArgumentException();
105 | }
106 | return FOR_BITS[bits];
107 | }
108 | }
109 | }
--------------------------------------------------------------------------------
/shadowsocks-csharp/3rd/zxing/qrcode/decoder/Mode.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2007 ZXing authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | using System;
18 |
19 | namespace ZXing.QrCode.Internal
20 | {
21 | ///
22 | /// See ISO 18004:2006, 6.4.1, Tables 2 and 3. This enum encapsulates the various modes in which
23 | /// data can be encoded to bits in the QR code standard.
24 | ///
25 | /// Sean Owen
26 | public sealed class Mode
27 | {
28 | ///
29 | /// Gets the name.
30 | ///
31 | public String Name
32 | {
33 | get
34 | {
35 | return name;
36 | }
37 | }
38 |
39 | // No, we can't use an enum here. J2ME doesn't support it.
40 |
41 | ///
42 | ///
43 | ///
44 | public static readonly Mode TERMINATOR = new Mode(new int[] { 0, 0, 0 }, 0x00, "TERMINATOR"); // Not really a mode...
45 | ///
46 | ///
47 | ///
48 | public static readonly Mode NUMERIC = new Mode(new int[] { 10, 12, 14 }, 0x01, "NUMERIC");
49 | ///
50 | ///
51 | ///
52 | public static readonly Mode ALPHANUMERIC = new Mode(new int[] { 9, 11, 13 }, 0x02, "ALPHANUMERIC");
53 | ///
54 | ///
55 | ///
56 | public static readonly Mode STRUCTURED_APPEND = new Mode(new int[] { 0, 0, 0 }, 0x03, "STRUCTURED_APPEND"); // Not supported
57 | ///
58 | ///
59 | ///
60 | public static readonly Mode BYTE = new Mode(new int[] { 8, 16, 16 }, 0x04, "BYTE");
61 | ///
62 | ///
63 | ///
64 | public static readonly Mode ECI = new Mode(null, 0x07, "ECI"); // character counts don't apply
65 | ///
66 | ///
67 | ///
68 | public static readonly Mode KANJI = new Mode(new int[] { 8, 10, 12 }, 0x08, "KANJI");
69 | ///
70 | ///
71 | ///
72 | public static readonly Mode FNC1_FIRST_POSITION = new Mode(null, 0x05, "FNC1_FIRST_POSITION");
73 | ///
74 | ///
75 | ///
76 | public static readonly Mode FNC1_SECOND_POSITION = new Mode(null, 0x09, "FNC1_SECOND_POSITION");
77 | /// See GBT 18284-2000; "Hanzi" is a transliteration of this mode name.
78 | public static readonly Mode HANZI = new Mode(new int[] { 8, 10, 12 }, 0x0D, "HANZI");
79 |
80 | private readonly int[] characterCountBitsForVersions;
81 | private readonly int bits;
82 | private readonly String name;
83 |
84 | private Mode(int[] characterCountBitsForVersions, int bits, System.String name)
85 | {
86 | this.characterCountBitsForVersions = characterCountBitsForVersions;
87 | this.bits = bits;
88 | this.name = name;
89 | }
90 |
91 | ///
92 | /// Fors the bits.
93 | ///
94 | /// four bits encoding a QR Code data mode
95 | ///
96 | /// encoded by these bits
97 | ///
98 | /// if bits do not correspond to a known mode
99 | public static Mode forBits(int bits)
100 | {
101 | switch (bits)
102 | {
103 | case 0x0:
104 | return TERMINATOR;
105 | case 0x1:
106 | return NUMERIC;
107 | case 0x2:
108 | return ALPHANUMERIC;
109 | case 0x3:
110 | return STRUCTURED_APPEND;
111 | case 0x4:
112 | return BYTE;
113 | case 0x5:
114 | return FNC1_FIRST_POSITION;
115 | case 0x7:
116 | return ECI;
117 | case 0x8:
118 | return KANJI;
119 | case 0x9:
120 | return FNC1_SECOND_POSITION;
121 | case 0xD:
122 | // 0xD is defined in GBT 18284-2000, may not be supported in foreign country
123 | return HANZI;
124 | default:
125 | throw new ArgumentException();
126 | }
127 | }
128 |
129 | /// version in question
130 | ///
131 | /// number of bits used, in this QR Code symbol {@link Version}, to encode the
132 | /// count of characters that will follow encoded in this {@link Mode}
133 | ///
134 | public int getCharacterCountBits(Version version)
135 | {
136 | if (characterCountBitsForVersions == null)
137 | {
138 | throw new ArgumentException("Character count doesn't apply to this mode");
139 | }
140 | int number = version.VersionNumber;
141 | int offset;
142 | if (number <= 9)
143 | {
144 | offset = 0;
145 | }
146 | else if (number <= 26)
147 | {
148 | offset = 1;
149 | }
150 | else
151 | {
152 | offset = 2;
153 | }
154 | return characterCountBitsForVersions[offset];
155 | }
156 |
157 | ///
158 | /// Gets the bits.
159 | ///
160 | public int Bits
161 | {
162 | get
163 | {
164 | return bits;
165 | }
166 | }
167 |
168 | ///
169 | /// Returns a that represents this instance.
170 | ///
171 | ///
172 | /// A that represents this instance.
173 | ///
174 | public override String ToString()
175 | {
176 | return name;
177 | }
178 | }
179 | }
--------------------------------------------------------------------------------
/shadowsocks-csharp/3rd/zxing/qrcode/decoder/QRCodeDecoderMetaData.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013 ZXing authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | namespace ZXing.QrCode.Internal
18 | {
19 | ///
20 | /// Meta-data container for QR Code decoding. Instances of this class may be used to convey information back to the
21 | /// decoding caller. Callers are expected to process this.
22 | ///
23 | public sealed class QRCodeDecoderMetaData
24 | {
25 | private readonly bool mirrored;
26 |
27 | ///
28 | /// Initializes a new instance of the class.
29 | ///
30 | /// if set to true [mirrored].
31 | public QRCodeDecoderMetaData(bool mirrored)
32 | {
33 | this.mirrored = mirrored;
34 | }
35 |
36 | ///
37 | /// true if the QR Code was mirrored.
38 | ///
39 | public bool IsMirrored
40 | {
41 | get { return mirrored; }
42 | }
43 |
44 | ///
45 | /// Apply the result points' order correction due to mirroring.
46 | ///
47 | /// Array of points to apply mirror correction to.
48 | public void applyMirroredCorrection(ResultPoint[] points)
49 | {
50 | if (!mirrored || points == null || points.Length < 3)
51 | {
52 | return;
53 | }
54 | ResultPoint bottomLeft = points[0];
55 | points[0] = points[2];
56 | points[2] = bottomLeft;
57 | // No need to 'fix' top-left and alignment pattern.
58 | }
59 | }
60 | }
--------------------------------------------------------------------------------
/shadowsocks-csharp/3rd/zxing/qrcode/detector/AlignmentPattern.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2007 ZXing authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | using System;
18 |
19 | namespace ZXing.QrCode.Internal
20 | {
21 | /// Encapsulates an alignment pattern, which are the smaller square patterns found in
22 | /// all but the simplest QR Codes.
23 | ///
24 | ///
25 | /// Sean Owen
26 | ///
27 | /// www.Redivivus.in (suraj.supekar@redivivus.in) - Ported from ZXING Java Source
28 | ///
29 | public sealed class AlignmentPattern : ResultPoint
30 | {
31 | private float estimatedModuleSize;
32 |
33 | internal AlignmentPattern(float posX, float posY, float estimatedModuleSize)
34 | : base(posX, posY)
35 | {
36 | this.estimatedModuleSize = estimatedModuleSize;
37 | }
38 |
39 | /// Determines if this alignment pattern "about equals" an alignment pattern at the stated
40 | /// position and size -- meaning, it is at nearly the same center with nearly the same size.
41 | ///
42 | internal bool aboutEquals(float moduleSize, float i, float j)
43 | {
44 | if (Math.Abs(i - Y) <= moduleSize && Math.Abs(j - X) <= moduleSize)
45 | {
46 | float moduleSizeDiff = Math.Abs(moduleSize - estimatedModuleSize);
47 | return moduleSizeDiff <= 1.0f || moduleSizeDiff <= estimatedModuleSize;
48 | }
49 | return false;
50 | }
51 |
52 | ///
53 | /// Combines this object's current estimate of a finder pattern position and module size
54 | /// with a new estimate. It returns a new {@code FinderPattern} containing an average of the two.
55 | ///
56 | /// The i.
57 | /// The j.
58 | /// New size of the module.
59 | ///
60 | internal AlignmentPattern combineEstimate(float i, float j, float newModuleSize)
61 | {
62 | float combinedX = (X + j) / 2.0f;
63 | float combinedY = (Y + i) / 2.0f;
64 | float combinedModuleSize = (estimatedModuleSize + newModuleSize) / 2.0f;
65 | return new AlignmentPattern(combinedX, combinedY, combinedModuleSize);
66 | }
67 | }
68 | }
--------------------------------------------------------------------------------
/shadowsocks-csharp/3rd/zxing/qrcode/detector/FinderPattern.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2007 ZXing authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | using System;
18 |
19 | namespace ZXing.QrCode.Internal
20 | {
21 | ///
22 | /// Encapsulates a finder pattern, which are the three square patterns found in
23 | /// the corners of QR Codes. It also encapsulates a count of similar finder patterns,
24 | /// as a convenience to the finder's bookkeeping.
25 | ///
26 | /// Sean Owen
27 | public sealed class FinderPattern : ResultPoint
28 | {
29 | private readonly float estimatedModuleSize;
30 | private int count;
31 |
32 | internal FinderPattern(float posX, float posY, float estimatedModuleSize)
33 | : this(posX, posY, estimatedModuleSize, 1)
34 | {
35 | this.estimatedModuleSize = estimatedModuleSize;
36 | this.count = 1;
37 | }
38 |
39 | internal FinderPattern(float posX, float posY, float estimatedModuleSize, int count)
40 | : base(posX, posY)
41 | {
42 | this.estimatedModuleSize = estimatedModuleSize;
43 | this.count = count;
44 | }
45 |
46 | ///
47 | /// Gets the size of the estimated module.
48 | ///
49 | ///
50 | /// The size of the estimated module.
51 | ///
52 | public float EstimatedModuleSize
53 | {
54 | get
55 | {
56 | return estimatedModuleSize;
57 | }
58 | }
59 |
60 | internal int Count
61 | {
62 | get
63 | {
64 | return count;
65 | }
66 | }
67 |
68 | /*
69 | internal void incrementCount()
70 | {
71 | this.count++;
72 | }
73 | */
74 |
75 | /// Determines if this finder pattern "about equals" a finder pattern at the stated
76 | /// position and size -- meaning, it is at nearly the same center with nearly the same size.
77 | ///
78 | internal bool aboutEquals(float moduleSize, float i, float j)
79 | {
80 | if (Math.Abs(i - Y) <= moduleSize && Math.Abs(j - X) <= moduleSize)
81 | {
82 | float moduleSizeDiff = Math.Abs(moduleSize - estimatedModuleSize);
83 | return moduleSizeDiff <= 1.0f || moduleSizeDiff <= estimatedModuleSize;
84 |
85 | }
86 | return false;
87 | }
88 |
89 | ///
90 | /// Combines this object's current estimate of a finder pattern position and module size
91 | /// with a new estimate. It returns a new {@code FinderPattern} containing a weighted average
92 | /// based on count.
93 | ///
94 | /// The i.
95 | /// The j.
96 | /// New size of the module.
97 | ///
98 | internal FinderPattern combineEstimate(float i, float j, float newModuleSize)
99 | {
100 | int combinedCount = count + 1;
101 | float combinedX = (count * X + j) / combinedCount;
102 | float combinedY = (count * Y + i) / combinedCount;
103 | float combinedModuleSize = (count * estimatedModuleSize + newModuleSize) / combinedCount;
104 | return new FinderPattern(combinedX, combinedY, combinedModuleSize, combinedCount);
105 | }
106 | }
107 | }
--------------------------------------------------------------------------------
/shadowsocks-csharp/3rd/zxing/qrcode/detector/FinderPatternInfo.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2007 ZXing authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | namespace ZXing.QrCode.Internal
18 | {
19 | ///
20 | /// Encapsulates information about finder patterns in an image, including the location of
21 | /// the three finder patterns, and their estimated module size.
22 | ///
23 | /// Sean Owen
24 | public sealed class FinderPatternInfo
25 | {
26 | private readonly FinderPattern bottomLeft;
27 | private readonly FinderPattern topLeft;
28 | private readonly FinderPattern topRight;
29 |
30 | ///
31 | /// Initializes a new instance of the class.
32 | ///
33 | /// The pattern centers.
34 | public FinderPatternInfo(FinderPattern[] patternCenters)
35 | {
36 | this.bottomLeft = patternCenters[0];
37 | this.topLeft = patternCenters[1];
38 | this.topRight = patternCenters[2];
39 | }
40 |
41 | ///
42 | /// Gets the bottom left.
43 | ///
44 | public FinderPattern BottomLeft
45 | {
46 | get
47 | {
48 | return bottomLeft;
49 | }
50 | }
51 |
52 | ///
53 | /// Gets the top left.
54 | ///
55 | public FinderPattern TopLeft
56 | {
57 | get
58 | {
59 | return topLeft;
60 | }
61 | }
62 |
63 | ///
64 | /// Gets the top right.
65 | ///
66 | public FinderPattern TopRight
67 | {
68 | get
69 | {
70 | return topRight;
71 | }
72 | }
73 | }
74 | }
--------------------------------------------------------------------------------
/shadowsocks-csharp/3rd/zxing/qrcode/encoder/BlockPair.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2008 ZXing authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | namespace ZXing.QrCode.Internal
18 | {
19 | internal sealed class BlockPair
20 | {
21 | private readonly byte[] dataBytes;
22 | private readonly byte[] errorCorrectionBytes;
23 |
24 | public BlockPair(byte[] data, byte[] errorCorrection)
25 | {
26 | dataBytes = data;
27 | errorCorrectionBytes = errorCorrection;
28 | }
29 |
30 | public byte[] DataBytes
31 | {
32 | get { return dataBytes; }
33 | }
34 |
35 | public byte[] ErrorCorrectionBytes
36 | {
37 | get { return errorCorrectionBytes; }
38 | }
39 | }
40 | }
--------------------------------------------------------------------------------
/shadowsocks-csharp/3rd/zxing/qrcode/encoder/ByteMatrix.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2008 ZXing authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | using System;
18 | using System.Text;
19 |
20 | namespace ZXing.QrCode.Internal
21 | {
22 | ///
23 | /// JAVAPORT: The original code was a 2D array of ints, but since it only ever gets assigned
24 | /// 0, 1 and 2 I'm going to use less memory and go with bytes.
25 | ///
26 | /// dswitkin@google.com (Daniel Switkin)
27 | public sealed class ByteMatrix
28 | {
29 | private readonly byte[][] bytes;
30 | private readonly int width;
31 | private readonly int height;
32 |
33 | ///
34 | /// Initializes a new instance of the class.
35 | ///
36 | /// The width.
37 | /// The height.
38 | public ByteMatrix(int width, int height)
39 | {
40 | bytes = new byte[height][];
41 | for (var i = 0; i < height; i++)
42 | bytes[i] = new byte[width];
43 | this.width = width;
44 | this.height = height;
45 | }
46 |
47 | ///
48 | /// Gets the height.
49 | ///
50 | public int Height
51 | {
52 | get { return height; }
53 | }
54 |
55 | ///
56 | /// Gets the width.
57 | ///
58 | public int Width
59 | {
60 | get { return width; }
61 | }
62 |
63 | ///
64 | /// Gets or sets the with the specified x.
65 | ///
66 | public int this[int x, int y]
67 | {
68 | get { return bytes[y][x]; }
69 | set { bytes[y][x] = (byte)value; }
70 | }
71 |
72 | ///
73 | /// an internal representation as bytes, in row-major order. array[y][x] represents point (x,y)
74 | ///
75 | public byte[][] Array
76 | {
77 | get { return bytes; }
78 | }
79 |
80 | ///
81 | /// Sets the specified x.
82 | ///
83 | /// The x.
84 | /// The y.
85 | /// The value.
86 | public void set(int x, int y, byte value)
87 | {
88 | bytes[y][x] = value;
89 | }
90 |
91 | ///
92 | /// Sets the specified x.
93 | ///
94 | /// The x.
95 | /// The y.
96 | /// if set to true [value].
97 | public void set(int x, int y, bool value)
98 | {
99 | bytes[y][x] = (byte)(value ? 1 : 0);
100 | }
101 |
102 | ///
103 | /// Clears the specified value.
104 | ///
105 | /// The value.
106 | public void clear(byte value)
107 | {
108 | for (int y = 0; y < height; ++y)
109 | {
110 | for (int x = 0; x < width; ++x)
111 | {
112 | bytes[y][x] = value;
113 | }
114 | }
115 | }
116 |
117 | ///
118 | /// Returns a that represents this instance.
119 | ///
120 | ///
121 | /// A that represents this instance.
122 | ///
123 | override public String ToString()
124 | {
125 | var result = new StringBuilder(2 * width * height + 2);
126 | for (int y = 0; y < height; ++y)
127 | {
128 | for (int x = 0; x < width; ++x)
129 | {
130 | switch (bytes[y][x])
131 | {
132 | case 0:
133 | result.Append(" 0");
134 | break;
135 | case 1:
136 | result.Append(" 1");
137 | break;
138 | default:
139 | result.Append(" ");
140 | break;
141 | }
142 | }
143 | result.Append('\n');
144 | }
145 | return result.ToString();
146 | }
147 | }
148 | }
--------------------------------------------------------------------------------
/shadowsocks-csharp/3rd/zxing/qrcode/encoder/QRCode.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2008 ZXing authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | using System;
18 | using System.Text;
19 |
20 | namespace ZXing.QrCode.Internal
21 | {
22 | /// satorux@google.com (Satoru Takabayashi) - creator
23 | /// dswitkin@google.com (Daniel Switkin) - ported from C++
24 | public sealed class QRCode
25 | {
26 | ///
27 | ///
28 | ///
29 | public static int NUM_MASK_PATTERNS = 8;
30 |
31 | ///
32 | /// Initializes a new instance of the class.
33 | ///
34 | public QRCode()
35 | {
36 | MaskPattern = -1;
37 | }
38 |
39 | ///
40 | /// Gets or sets the mode.
41 | ///
42 | ///
43 | /// The mode.
44 | ///
45 | public Mode Mode { get; set; }
46 |
47 | ///
48 | /// Gets or sets the EC level.
49 | ///
50 | ///
51 | /// The EC level.
52 | ///
53 | public ErrorCorrectionLevel ECLevel { get; set; }
54 |
55 | ///
56 | /// Gets or sets the version.
57 | ///
58 | ///
59 | /// The version.
60 | ///
61 | public Version Version { get; set; }
62 |
63 | ///
64 | /// Gets or sets the mask pattern.
65 | ///
66 | ///
67 | /// The mask pattern.
68 | ///
69 | public int MaskPattern { get; set; }
70 |
71 | ///
72 | /// Gets or sets the matrix.
73 | ///
74 | ///
75 | /// The matrix.
76 | ///
77 | public ByteMatrix Matrix { get; set; }
78 |
79 | ///
80 | /// Returns a that represents this instance.
81 | ///
82 | ///
83 | /// A that represents this instance.
84 | ///
85 | public override String ToString()
86 | {
87 | var result = new StringBuilder(200);
88 | result.Append("<<\n");
89 | result.Append(" mode: ");
90 | result.Append(Mode);
91 | result.Append("\n ecLevel: ");
92 | result.Append(ECLevel);
93 | result.Append("\n version: ");
94 | if (Version == null)
95 | result.Append("null");
96 | else
97 | result.Append(Version);
98 | result.Append("\n maskPattern: ");
99 | result.Append(MaskPattern);
100 | if (Matrix == null)
101 | {
102 | result.Append("\n matrix: null\n");
103 | }
104 | else
105 | {
106 | result.Append("\n matrix:\n");
107 | result.Append(Matrix.ToString());
108 | }
109 | result.Append(">>\n");
110 | return result.ToString();
111 | }
112 |
113 | ///
114 | /// Check if "mask_pattern" is valid.
115 | ///
116 | /// The mask pattern.
117 | ///
118 | /// true if [is valid mask pattern] [the specified mask pattern]; otherwise, false.
119 | ///
120 | public static bool isValidMaskPattern(int maskPattern)
121 | {
122 | return maskPattern >= 0 && maskPattern < NUM_MASK_PATTERNS;
123 | }
124 | }
125 | }
--------------------------------------------------------------------------------
/shadowsocks-csharp/Controller/FileManager.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.IO.Compression;
5 | using System.Text;
6 |
7 | namespace Shadowsocks.Controller
8 | {
9 | public class FileManager
10 | {
11 | public static bool ByteArrayToFile(string fileName, byte[] content)
12 | {
13 | try
14 | {
15 | System.IO.FileStream _FileStream =
16 | new System.IO.FileStream(fileName, System.IO.FileMode.Create,
17 | System.IO.FileAccess.Write);
18 | _FileStream.Write(content, 0, content.Length);
19 | _FileStream.Close();
20 | return true;
21 | }
22 | catch (Exception _Exception)
23 | {
24 | Console.WriteLine("Exception caught in process: {0}",
25 | _Exception.ToString());
26 | }
27 | return false;
28 | }
29 |
30 | public static void UncompressFile(string fileName, byte[] content)
31 | {
32 | FileStream destinationFile = File.Create(fileName);
33 |
34 | // Because the uncompressed size of the file is unknown,
35 | // we are using an arbitrary buffer size.
36 | byte[] buffer = new byte[4096];
37 | int n;
38 |
39 | using (GZipStream input = new GZipStream(new MemoryStream(content),
40 | CompressionMode.Decompress, false))
41 | {
42 | while (true)
43 | {
44 | n = input.Read(buffer, 0, buffer.Length);
45 | if (n == 0)
46 | {
47 | break;
48 | }
49 | destinationFile.Write(buffer, 0, n);
50 | }
51 | }
52 | destinationFile.Close();
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Controller/I18N.cs:
--------------------------------------------------------------------------------
1 | using Shadowsocks.Properties;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Text;
5 | using System.Text.RegularExpressions;
6 |
7 | namespace Shadowsocks.Controller
8 | {
9 | public class I18N
10 | {
11 | protected static Dictionary Strings;
12 | static I18N()
13 | {
14 | Strings = new Dictionary();
15 |
16 | if (System.Globalization.CultureInfo.CurrentCulture.IetfLanguageTag.ToLowerInvariant().StartsWith("zh"))
17 | {
18 | string[] lines = Regex.Split(Resources.cn, "\r\n|\r|\n");
19 | foreach (string line in lines)
20 | {
21 | if (line.StartsWith("#"))
22 | {
23 | continue;
24 | }
25 | string[] kv = Regex.Split(line, "=");
26 | if (kv.Length == 2)
27 | {
28 | Strings[kv[0]] = kv[1];
29 | }
30 | }
31 | }
32 | }
33 |
34 | public static string GetString(string key)
35 | {
36 | if (Strings.ContainsKey(key))
37 | {
38 | return Strings[key];
39 | }
40 | else
41 | {
42 | return key;
43 | }
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Controller/Logging.cs:
--------------------------------------------------------------------------------
1 | using Shadowsocks.Util;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.IO;
5 | using System.Net.Sockets;
6 | using System.Text;
7 |
8 | namespace Shadowsocks.Controller
9 | {
10 | public class Logging
11 | {
12 | public static string LogFile;
13 |
14 | public static bool OpenLogFile()
15 | {
16 | try
17 | {
18 | string temppath = Utils.GetTempPath();
19 | LogFile = Path.Combine(temppath, "shadowsocks.log");
20 | FileStream fs = new FileStream(LogFile, FileMode.Append);
21 | StreamWriterWithTimestamp sw = new StreamWriterWithTimestamp(fs);
22 | sw.AutoFlush = true;
23 | Console.SetOut(sw);
24 | Console.SetError(sw);
25 |
26 | return true;
27 | }
28 | catch (IOException e)
29 | {
30 | Console.WriteLine(e.ToString());
31 | return false;
32 | }
33 | }
34 |
35 | public static void Debug(object o)
36 | {
37 |
38 | #if DEBUG
39 | Console.WriteLine(o);
40 | #endif
41 | }
42 |
43 | public static void LogUsefulException(Exception e)
44 | {
45 | // just log useful exceptions, not all of them
46 | if (e is SocketException)
47 | {
48 | SocketException se = (SocketException)e;
49 | if (se.SocketErrorCode == SocketError.ConnectionAborted)
50 | {
51 | // closed by browser when sending
52 | // normally happens when download is canceled or a tab is closed before page is loaded
53 | }
54 | else if (se.SocketErrorCode == SocketError.ConnectionReset)
55 | {
56 | // received rst
57 | }
58 | else if (se.SocketErrorCode == SocketError.NotConnected)
59 | {
60 | // close when not connected
61 | }
62 | else
63 | {
64 | Console.WriteLine(e);
65 | }
66 | }
67 | else if (e is ObjectDisposedException)
68 | {
69 | }
70 | else
71 | {
72 | Console.WriteLine(e);
73 | }
74 | }
75 | }
76 |
77 | // Simply extended System.IO.StreamWriter for adding timestamp workaround
78 | public class StreamWriterWithTimestamp : StreamWriter
79 | {
80 | public StreamWriterWithTimestamp(Stream stream) : base(stream)
81 | {
82 | }
83 |
84 | private string GetTimestamp()
85 | {
86 | return "[" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "] ";
87 | }
88 |
89 | public override void WriteLine(string value)
90 | {
91 | base.WriteLine(GetTimestamp() + value);
92 | }
93 |
94 | public override void Write(string value)
95 | {
96 | base.Write(GetTimestamp() + value);
97 | }
98 | }
99 |
100 | }
101 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Controller/Service/AvailabilityStatistics.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Net.NetworkInformation;
6 | using System.Threading;
7 | using Shadowsocks.Model;
8 | using System.Reflection;
9 | using Shadowsocks.Util;
10 |
11 | namespace Shadowsocks.Controller
12 | {
13 | class AvailabilityStatistics
14 | {
15 | private static readonly string StatisticsFilesName = "shadowsocks.availability.csv";
16 | private static readonly string Delimiter = ",";
17 | private static readonly int Timeout = 500;
18 | private static readonly int Repeat = 4; //repeat times every evaluation
19 | private static readonly int Interval = 10 * 60 * 1000; //evaluate proxies every 15 minutes
20 | private Timer timer = null;
21 | private State state = null;
22 | private List servers;
23 |
24 | public static string AvailabilityStatisticsFile;
25 |
26 | //static constructor to initialize every public static fields before refereced
27 | static AvailabilityStatistics()
28 | {
29 | string temppath = Utils.GetTempPath();
30 | AvailabilityStatisticsFile = Path.Combine(temppath, StatisticsFilesName);
31 | }
32 |
33 | public bool Set(bool enabled)
34 | {
35 | try
36 | {
37 | if (enabled)
38 | {
39 | if (timer?.Change(0, Interval) == null)
40 | {
41 | state = new State();
42 | timer = new Timer(Evaluate, state, 0, Interval);
43 | }
44 | }
45 | else
46 | {
47 | timer?.Dispose();
48 | }
49 | return true;
50 | }
51 | catch (Exception e)
52 | {
53 | Logging.LogUsefulException(e);
54 | return false;
55 | }
56 | }
57 |
58 | private void Evaluate(object obj)
59 | {
60 | Ping ping = new Ping();
61 | State state = (State) obj;
62 | foreach (var server in servers)
63 | {
64 | Logging.Debug("eveluating " + server.FriendlyName());
65 | foreach (var _ in Enumerable.Range(0, Repeat))
66 | {
67 | //TODO: do simple analyze of data to provide friendly message, like package loss.
68 | string timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
69 | //ICMP echo. we can also set options and special bytes
70 | //seems no need to use SendPingAsync
71 | try
72 | {
73 | PingReply reply = ping.Send(server.server, Timeout);
74 | state.data = new List>();
75 | state.data.Add(new KeyValuePair("Timestamp", timestamp));
76 | state.data.Add(new KeyValuePair("Server", server.FriendlyName()));
77 | state.data.Add(new KeyValuePair("Status", reply.Status.ToString()));
78 | state.data.Add(new KeyValuePair("RoundtripTime", reply.RoundtripTime.ToString()));
79 | //state.data.Add(new KeyValuePair("data", reply.Buffer.ToString())); // The data of reply
80 | Append(state.data);
81 | }
82 | catch (Exception e)
83 | {
84 | Logging.LogUsefulException(e);
85 | }
86 | }
87 | }
88 | }
89 |
90 | private static void Append(List> data)
91 | {
92 | string dataLine = string.Join(Delimiter, data.Select(kv => kv.Value).ToArray());
93 | string[] lines;
94 | if (!File.Exists(AvailabilityStatisticsFile))
95 | {
96 | string headerLine = string.Join(Delimiter, data.Select(kv => kv.Key).ToArray());
97 | lines = new string[] { headerLine, dataLine };
98 | }
99 | else
100 | {
101 | lines = new string[] { dataLine };
102 | }
103 | File.AppendAllLines(AvailabilityStatisticsFile, lines);
104 | }
105 |
106 | internal void UpdateConfiguration(Configuration _config)
107 | {
108 | Set(_config.availabilityStatistics);
109 | servers = _config.configs;
110 | }
111 |
112 | private class State
113 | {
114 | public List> data = new List>();
115 | }
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Controller/Service/GfwListUpdater.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.Net;
5 | using System.IO;
6 | using Shadowsocks.Properties;
7 | using SimpleJson;
8 | using Shadowsocks.Util;
9 | using Shadowsocks.Model;
10 |
11 | namespace Shadowsocks.Controller
12 | {
13 | public class GFWListUpdater
14 | {
15 | private const string GFWLIST_URL = "https://autoproxy-gfwlist.googlecode.com/svn/trunk/gfwlist.txt";
16 |
17 | private static string PAC_FILE = PACServer.PAC_FILE;
18 |
19 | private static string USER_RULE_FILE = PACServer.USER_RULE_FILE;
20 |
21 | public event EventHandler UpdateCompleted;
22 |
23 | public event ErrorEventHandler Error;
24 |
25 | public class ResultEventArgs : EventArgs
26 | {
27 | public bool Success;
28 |
29 | public ResultEventArgs(bool success)
30 | {
31 | this.Success = success;
32 | }
33 | }
34 |
35 | private void http_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
36 | {
37 | try
38 | {
39 | List lines = ParseResult(e.Result);
40 | if (File.Exists(USER_RULE_FILE))
41 | {
42 | string local = File.ReadAllText(USER_RULE_FILE, Encoding.UTF8);
43 | string[] rules = local.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
44 | foreach(string rule in rules)
45 | {
46 | if (rule.StartsWith("!") || rule.StartsWith("["))
47 | continue;
48 | lines.Add(rule);
49 | }
50 | }
51 | string abpContent = Utils.UnGzip(Resources.abp_js);
52 | abpContent = abpContent.Replace("__RULES__", SimpleJson.SimpleJson.SerializeObject(lines));
53 | if (File.Exists(PAC_FILE))
54 | {
55 | string original = File.ReadAllText(PAC_FILE, Encoding.UTF8);
56 | if (original == abpContent)
57 | {
58 | UpdateCompleted(this, new ResultEventArgs(false));
59 | return;
60 | }
61 | }
62 | File.WriteAllText(PAC_FILE, abpContent, Encoding.UTF8);
63 | if (UpdateCompleted != null)
64 | {
65 | UpdateCompleted(this, new ResultEventArgs(true));
66 | }
67 | }
68 | catch (Exception ex)
69 | {
70 | if (Error != null)
71 | {
72 | Error(this, new ErrorEventArgs(ex));
73 | }
74 | }
75 | }
76 |
77 | public void UpdatePACFromGFWList(Configuration config)
78 | {
79 | WebClient http = new WebClient();
80 | http.Proxy = new WebProxy(IPAddress.Loopback.ToString(), config.localPort);
81 | http.DownloadStringCompleted += http_DownloadStringCompleted;
82 | http.DownloadStringAsync(new Uri(GFWLIST_URL));
83 | }
84 |
85 | public List ParseResult(string response)
86 | {
87 | byte[] bytes = Convert.FromBase64String(response);
88 | string content = Encoding.ASCII.GetString(bytes);
89 | string[] lines = content.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
90 | List valid_lines = new List(lines.Length);
91 | foreach (string line in lines)
92 | {
93 | if (line.StartsWith("!") || line.StartsWith("["))
94 | continue;
95 | valid_lines.Add(line);
96 | }
97 | return valid_lines;
98 | }
99 | }
100 | }
--------------------------------------------------------------------------------
/shadowsocks-csharp/Controller/Service/UpdateChecker.cs:
--------------------------------------------------------------------------------
1 | using Shadowsocks.Model;
2 | using System;
3 | using System.Collections;
4 | using System.Collections.Generic;
5 | using System.Net;
6 | using System.Reflection;
7 | using System.Text;
8 | using System.Text.RegularExpressions;
9 | using SimpleJson;
10 |
11 | namespace Shadowsocks.Controller
12 | {
13 | public class UpdateChecker
14 | {
15 | private const string UpdateURL = "https://api.github.com/repos/shadowsocks/shadowsocks-windows/releases";
16 |
17 | public string LatestVersionNumber;
18 | public string LatestVersionURL;
19 | public event EventHandler NewVersionFound;
20 |
21 | public const string Version = "2.5.6";
22 |
23 | public void CheckUpdate(Configuration config)
24 | {
25 | // TODO test failures
26 | WebClient http = new WebClient();
27 | http.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.3319.102 Safari/537.36");
28 | http.Proxy = new WebProxy(IPAddress.Loopback.ToString(), config.localPort);
29 | http.DownloadStringCompleted += http_DownloadStringCompleted;
30 | http.DownloadStringAsync(new Uri(UpdateURL));
31 | }
32 |
33 | public static int CompareVersion(string l, string r)
34 | {
35 | var ls = l.Split('.');
36 | var rs = r.Split('.');
37 | for (int i = 0; i < Math.Max(ls.Length, rs.Length); i++)
38 | {
39 | int lp = (i < ls.Length) ? int.Parse(ls[i]) : 0;
40 | int rp = (i < rs.Length) ? int.Parse(rs[i]) : 0;
41 | if (lp != rp)
42 | {
43 | return lp - rp;
44 | }
45 | }
46 | return 0;
47 | }
48 |
49 | public class VersionComparer : IComparer
50 | {
51 | // Calls CaseInsensitiveComparer.Compare with the parameters reversed.
52 | public int Compare(string x, string y)
53 | {
54 | return CompareVersion(ParseVersionFromURL(x), ParseVersionFromURL(y));
55 | }
56 | }
57 |
58 | private static string ParseVersionFromURL(string url)
59 | {
60 | Match match = Regex.Match(url, @".*Shadowsocks-win.*?-([\d\.]+)\.\w+", RegexOptions.IgnoreCase);
61 | if (match.Success)
62 | {
63 | if (match.Groups.Count == 2)
64 | {
65 | return match.Groups[1].Value;
66 | }
67 | }
68 | return null;
69 | }
70 |
71 | private void SortVersions(List versions)
72 | {
73 | versions.Sort(new VersionComparer());
74 | }
75 |
76 | private bool IsNewVersion(string url)
77 | {
78 | if (url.IndexOf("prerelease") >= 0)
79 | {
80 | return false;
81 | }
82 | string version = ParseVersionFromURL(url);
83 | if (version == null)
84 | {
85 | return false;
86 | }
87 | string currentVersion = Version;
88 |
89 | return CompareVersion(version, currentVersion) > 0;
90 | }
91 |
92 | private void http_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
93 | {
94 | try
95 | {
96 | string response = e.Result;
97 |
98 | JsonArray result = (JsonArray)SimpleJson.SimpleJson.DeserializeObject(e.Result);
99 |
100 | List versions = new List();
101 | foreach (JsonObject release in result)
102 | {
103 | if ((bool)release["prerelease"])
104 | {
105 | continue;
106 | }
107 | foreach (JsonObject asset in (JsonArray)release["assets"])
108 | {
109 | string url = (string)asset["browser_download_url"];
110 | if (IsNewVersion(url))
111 | {
112 | versions.Add(url);
113 | }
114 | }
115 | }
116 |
117 | if (versions.Count == 0)
118 | {
119 | return;
120 | }
121 | // sort versions
122 | SortVersions(versions);
123 | LatestVersionURL = versions[versions.Count - 1];
124 | LatestVersionNumber = ParseVersionFromURL(LatestVersionURL);
125 | if (NewVersionFound != null)
126 | {
127 | NewVersionFound(this, new EventArgs());
128 | }
129 | }
130 | catch (Exception ex)
131 | {
132 | Logging.Debug(ex.ToString());
133 | return;
134 | }
135 | }
136 | }
137 | }
138 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Controller/Strategy/BalancingStrategy.cs:
--------------------------------------------------------------------------------
1 | using Shadowsocks.Controller;
2 | using Shadowsocks.Model;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Net;
6 | using System.Text;
7 |
8 | namespace Shadowsocks.Controller.Strategy
9 | {
10 | class BalancingStrategy : IStrategy
11 | {
12 | ShadowsocksController _controller;
13 | Random _random;
14 |
15 | public BalancingStrategy(ShadowsocksController controller)
16 | {
17 | _controller = controller;
18 | _random = new Random();
19 | }
20 |
21 | public string Name
22 | {
23 | get { return I18N.GetString("Load Balance"); }
24 | }
25 |
26 | public string ID
27 | {
28 | get { return "com.shadowsocks.strategy.balancing"; }
29 | }
30 |
31 | public void ReloadServers()
32 | {
33 | // do nothing
34 | }
35 |
36 | public Server GetAServer(IStrategyCallerType type, IPEndPoint localIPEndPoint)
37 | {
38 | var configs = _controller.GetCurrentConfiguration().configs;
39 | int index;
40 | if (type == IStrategyCallerType.TCP)
41 | {
42 | index = _random.Next();
43 | }
44 | else
45 | {
46 | index = localIPEndPoint.GetHashCode();
47 | }
48 | return configs[index % configs.Count];
49 | }
50 |
51 | public void UpdateLatency(Model.Server server, TimeSpan latency)
52 | {
53 | // do nothing
54 | }
55 |
56 | public void UpdateLastRead(Model.Server server)
57 | {
58 | // do nothing
59 | }
60 |
61 | public void UpdateLastWrite(Model.Server server)
62 | {
63 | // do nothing
64 | }
65 |
66 | public void SetFailure(Model.Server server)
67 | {
68 | // do nothing
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Controller/Strategy/IStrategy.cs:
--------------------------------------------------------------------------------
1 | using Shadowsocks.Model;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Net;
5 | using System.Text;
6 |
7 | namespace Shadowsocks.Controller.Strategy
8 | {
9 | public enum IStrategyCallerType
10 | {
11 | TCP,
12 | UDP
13 | }
14 |
15 | /*
16 | * IStrategy
17 | *
18 | * Subclasses must be thread-safe
19 | */
20 | public interface IStrategy
21 | {
22 | string Name { get; }
23 |
24 | string ID { get; }
25 |
26 | /*
27 | * Called when servers need to be reloaded, i.e. new configuration saved
28 | */
29 | void ReloadServers();
30 |
31 | /*
32 | * Get a new server to use in TCPRelay or UDPRelay
33 | */
34 | Server GetAServer(IStrategyCallerType type, IPEndPoint localIPEndPoint);
35 |
36 | /*
37 | * TCPRelay will call this when latency of a server detected
38 | */
39 | void UpdateLatency(Server server, TimeSpan latency);
40 |
41 | /*
42 | * TCPRelay will call this when reading from a server
43 | */
44 | void UpdateLastRead(Server server);
45 |
46 | /*
47 | * TCPRelay will call this when writing to a server
48 | */
49 | void UpdateLastWrite(Server server);
50 |
51 | /*
52 | * TCPRelay will call this when fatal failure detected
53 | */
54 | void SetFailure(Server server);
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Controller/Strategy/StrategyManager.cs:
--------------------------------------------------------------------------------
1 | using Shadowsocks.Controller;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Text;
5 |
6 | namespace Shadowsocks.Controller.Strategy
7 | {
8 | class StrategyManager
9 | {
10 | List _strategies;
11 | public StrategyManager(ShadowsocksController controller)
12 | {
13 | _strategies = new List();
14 | _strategies.Add(new BalancingStrategy(controller));
15 | _strategies.Add(new HighAvailabilityStrategy(controller));
16 | _strategies.Add(new SimplyChooseByStatisticsStrategy(controller));
17 | // TODO: load DLL plugins
18 | }
19 | public IList GetStrategies()
20 | {
21 | return _strategies;
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Controller/System/AutoStartup.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Windows.Forms;
3 | using Microsoft.Win32;
4 |
5 | namespace Shadowsocks.Controller
6 | {
7 | class AutoStartup
8 | {
9 | public static bool Set(bool enabled)
10 | {
11 | try
12 | {
13 | string path = Application.ExecutablePath;
14 | RegistryKey runKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Run", true);
15 | if (enabled)
16 | {
17 | runKey.SetValue("Shadowsocks", path);
18 | }
19 | else
20 | {
21 | runKey.DeleteValue("Shadowsocks");
22 | }
23 | runKey.Close();
24 | return true;
25 | }
26 | catch (Exception e)
27 | {
28 | Logging.LogUsefulException(e);
29 | return false;
30 | }
31 | }
32 |
33 | public static bool Check()
34 | {
35 | try
36 | {
37 | string path = Application.ExecutablePath;
38 | RegistryKey runKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Run");
39 | string[] runList = runKey.GetValueNames();
40 | runKey.Close();
41 | foreach (string item in runList)
42 | {
43 | if (item.Equals("Shadowsocks"))
44 | return true;
45 | }
46 | return false;
47 | }
48 | catch (Exception e)
49 | {
50 | Logging.LogUsefulException(e);
51 | return false;
52 | }
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Controller/System/SystemProxy.cs:
--------------------------------------------------------------------------------
1 | using System.Windows.Forms;
2 | using Microsoft.Win32;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Runtime.InteropServices;
6 | using System.Text;
7 | using System.IO;
8 | using Shadowsocks.Model;
9 |
10 | namespace Shadowsocks.Controller
11 | {
12 | public class SystemProxy
13 | {
14 |
15 | [DllImport("wininet.dll")]
16 | public static extern bool InternetSetOption(IntPtr hInternet, int dwOption, IntPtr lpBuffer, int dwBufferLength);
17 | public const int INTERNET_OPTION_SETTINGS_CHANGED = 39;
18 | public const int INTERNET_OPTION_REFRESH = 37;
19 | static bool _settingsReturn, _refreshReturn;
20 |
21 | public static void NotifyIE()
22 | {
23 | // These lines implement the Interface in the beginning of program
24 | // They cause the OS to refresh the settings, causing IP to realy update
25 | _settingsReturn = InternetSetOption(IntPtr.Zero, INTERNET_OPTION_SETTINGS_CHANGED, IntPtr.Zero, 0);
26 | _refreshReturn = InternetSetOption(IntPtr.Zero, INTERNET_OPTION_REFRESH, IntPtr.Zero, 0);
27 | }
28 |
29 | public static void Update(Configuration config, bool forceDisable)
30 | {
31 | bool global = config.global;
32 | bool enabled = config.enabled;
33 | if (forceDisable)
34 | {
35 | enabled = false;
36 | }
37 | try
38 | {
39 | RegistryKey registry =
40 | Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",
41 | true);
42 | if (enabled)
43 | {
44 | if (global)
45 | {
46 | registry.SetValue("ProxyEnable", 1);
47 | registry.SetValue("ProxyServer", "127.0.0.1:" + config.localPort.ToString());
48 | registry.SetValue("AutoConfigURL", "");
49 | }
50 | else
51 | {
52 | string pacUrl;
53 | if (config.useOnlinePac && !string.IsNullOrEmpty(config.pacUrl))
54 | pacUrl = config.pacUrl;
55 | else
56 | pacUrl = "http://127.0.0.1:" + config.localPort.ToString() + "/pac?t=" + GetTimestamp(DateTime.Now);
57 | registry.SetValue("ProxyEnable", 0);
58 | var readProxyServer = registry.GetValue("ProxyServer");
59 | registry.SetValue("ProxyServer", "");
60 | registry.SetValue("AutoConfigURL", pacUrl);
61 | }
62 | }
63 | else
64 | {
65 | registry.SetValue("ProxyEnable", 0);
66 | registry.SetValue("ProxyServer", "");
67 | registry.SetValue("AutoConfigURL", "");
68 | }
69 | //Set AutoDetectProxy Off
70 | IEAutoDetectProxy(false);
71 | SystemProxy.NotifyIE();
72 | //Must Notify IE first, or the connections do not chanage
73 | CopyProxySettingFromLan();
74 | }
75 | catch (Exception e)
76 | {
77 | Logging.LogUsefulException(e);
78 | // TODO this should be moved into views
79 | MessageBox.Show(I18N.GetString("Failed to update registry"));
80 | }
81 | }
82 |
83 | private static void CopyProxySettingFromLan()
84 | {
85 | RegistryKey registry =
86 | Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Connections",
87 | true);
88 | var defaultValue = registry.GetValue("DefaultConnectionSettings");
89 | try
90 | {
91 | var connections = registry.GetValueNames();
92 | foreach (String each in connections)
93 | {
94 | if (!(each.Equals("DefaultConnectionSettings")
95 | || each.Equals("LAN Connection")
96 | || each.Equals("SavedLegacySettings")))
97 | {
98 | //set all the connections's proxy as the lan
99 | registry.SetValue(each, defaultValue);
100 | }
101 | }
102 | SystemProxy.NotifyIE();
103 | } catch (IOException e) {
104 | Logging.LogUsefulException(e);
105 | }
106 | }
107 |
108 | private static String GetTimestamp(DateTime value)
109 | {
110 | return value.ToString("yyyyMMddHHmmssffff");
111 | }
112 |
113 | ///
114 | /// Checks or unchecks the IE Options Connection setting of "Automatically detect Proxy"
115 | ///
116 | /// Provide 'true' if you want to check the 'Automatically detect Proxy' check box. To uncheck, pass 'false'
117 | private static void IEAutoDetectProxy(bool set)
118 | {
119 | RegistryKey registry =
120 | Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Connections",
121 | true);
122 | byte[] defConnection = (byte[])registry.GetValue("DefaultConnectionSettings");
123 | byte[] savedLegacySetting = (byte[])registry.GetValue("SavedLegacySettings");
124 | if (set)
125 | {
126 | defConnection[8] = Convert.ToByte(defConnection[8] & 8);
127 | savedLegacySetting[8] = Convert.ToByte(savedLegacySetting[8] & 8);
128 | }
129 | else
130 | {
131 | defConnection[8] = Convert.ToByte(defConnection[8] & ~8);
132 | savedLegacySetting[8] = Convert.ToByte(savedLegacySetting[8] & ~8);
133 | }
134 | registry.SetValue("DefaultConnectionSettings", defConnection);
135 | registry.SetValue("SavedLegacySettings", savedLegacySetting);
136 | }
137 | }
138 | }
139 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Data/abp.js.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Long-live-shadowsocks/shadowsocks-windows/b07a9ef3b06a5fd9646aa1e502319afdb6f578c8/shadowsocks-csharp/Data/abp.js.gz
--------------------------------------------------------------------------------
/shadowsocks-csharp/Data/cn.txt:
--------------------------------------------------------------------------------
1 | # translation for Simplified Chinese
2 |
3 | Shadowsocks=Shadowsocks
4 |
5 | # Menu items
6 |
7 | Enable System Proxy=启用系统代理
8 | Mode=系统代理模式
9 | PAC=PAC 模式
10 | Global=全局模式
11 | Servers=服务器
12 | Edit Servers...=编辑服务器...
13 | Start on Boot=开机启动
14 | Allow Clients from LAN=允许来自局域网的连接
15 | Local PAC=使用本地 PAC
16 | Online PAC=使用在线 PAC
17 | Edit Local PAC File...=编辑本地 PAC 文件...
18 | Update Local PAC from GFWList=从 GFWList 更新本地 PAC
19 | Edit User Rule for GFWList...=编辑 GFWList 的用户规则...
20 | Show QRCode...=显示二维码...
21 | Scan QRCode from Screen...=扫描屏幕上的二维码...
22 | Availability Statistics=统计可用性
23 | Show Logs...=显示日志...
24 | About...=关于...
25 | Quit=退出
26 | Edit Servers=编辑服务器
27 | Load Balance=负载均衡
28 | High Availability=高可用
29 | Choose By Total Package Loss=累计丢包率
30 |
31 | # Config Form
32 |
33 | &Add=添加(&A)
34 | &Delete=删除(&D)
35 | Server=服务器
36 | Server IP=服务器 IP
37 | Server Port=服务器端口
38 | Password=密码
39 | Encryption=加密
40 | Proxy Port=代理端口
41 | Remarks=备注
42 | OK=确定
43 | Cancel=取消
44 | New server=未配置的服务器
45 | Move &Up=上移(&U)
46 | Move D&own=下移(&O)
47 |
48 | # Log Form
49 |
50 | &File=文件(&F)
51 | &Open Location=在资源管理器中打开(&O)
52 | E&xit=退出(&X)
53 | &Clean logs=清空(&C)
54 | &Font=字体(&F)
55 | &Wrap text=自动换行(&W)
56 | &Top most=置顶(&T)
57 | Log Viewer=日志查看器
58 |
59 | # QRCode Form
60 |
61 | QRCode=二维码
62 |
63 | # PAC Url Form
64 |
65 | Edit Online PAC URL=编辑在线 PAC 网址
66 | Edit Online PAC URL...=编辑在线 PAC 网址...
67 | Please input PAC Url=请输入 PAC 网址
68 |
69 | # Messages
70 |
71 | Shadowsocks Error: {0}=Shadowsocks 错误: {0}
72 | Port already in use=端口已被占用
73 | Illegal port number format=非法端口格式
74 | Please add at least one server=请添加至少一个服务器
75 | Server IP can not be blank=服务器 IP 不能为空
76 | Password can not be blank=密码不能为空
77 | Port out of range=端口超出范围
78 | Port can't be 8123=端口不能为 8123
79 | Shadowsocks {0} Update Found=Shadowsocks {0} 更新
80 | Click here to download=点击这里下载
81 | Shadowsocks is here=Shadowsocks 在这里
82 | You can turn on/off Shadowsocks in the context menu=可以在右键菜单中开关 Shadowsocks
83 | System Proxy Enabled=系统代理已启用
84 | System Proxy Disabled=系统代理未启用
85 | Failed to update PAC file =更新 PAC 文件失败
86 | PAC updated=更新 PAC 成功
87 | No updates found. Please report to GFWList if you have problems with it.=未发现更新。如有问题请提交给 GFWList。
88 | No QRCode found. Try to zoom in or move it to the center of the screen.=未发现二维码,尝试把它放大或移动到靠近屏幕中间的位置
89 | Shadowsocks is already running.=Shadowsocks 已经在运行。
90 | Find Shadowsocks icon in your notify tray.=请在任务栏里寻找 Shadowsocks 图标。
91 | If you want to start multiple Shadowsocks, make a copy in another directory.=如果想同时启动多个,可以另外复制一份到别的目录。
92 | Failed to decode QRCode=无法解析二维码
93 | Failed to update registry=无法修改注册表
94 | System Proxy On: =系统代理已启用:
95 | Running: Port {0}=正在运行:端口 {0}
96 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Data/libsscrypto.dll.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Long-live-shadowsocks/shadowsocks-windows/b07a9ef3b06a5fd9646aa1e502319afdb6f578c8/shadowsocks-csharp/Data/libsscrypto.dll.gz
--------------------------------------------------------------------------------
/shadowsocks-csharp/Data/mgwz.dll.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Long-live-shadowsocks/shadowsocks-windows/b07a9ef3b06a5fd9646aa1e502319afdb6f578c8/shadowsocks-csharp/Data/mgwz.dll.gz
--------------------------------------------------------------------------------
/shadowsocks-csharp/Data/privoxy.exe.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Long-live-shadowsocks/shadowsocks-windows/b07a9ef3b06a5fd9646aa1e502319afdb6f578c8/shadowsocks-csharp/Data/privoxy.exe.gz
--------------------------------------------------------------------------------
/shadowsocks-csharp/Data/privoxy_conf.txt:
--------------------------------------------------------------------------------
1 | listen-address __POLIPO_BIND_IP__:8123
2 | show-on-task-bar 0
3 | activity-animation 0
4 | forward-socks5 / 127.0.0.1:__SOCKS_PORT__ .
5 | hide-console
--------------------------------------------------------------------------------
/shadowsocks-csharp/Data/proxy.pac.txt.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Long-live-shadowsocks/shadowsocks-windows/b07a9ef3b06a5fd9646aa1e502319afdb6f578c8/shadowsocks-csharp/Data/proxy.pac.txt.gz
--------------------------------------------------------------------------------
/shadowsocks-csharp/Data/user-rule.txt:
--------------------------------------------------------------------------------
1 | ! Put user rules line by line in this file.
2 | ! See https://adblockplus.org/en/filter-cheatsheet
3 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Encryption/EncryptorBase.cs:
--------------------------------------------------------------------------------
1 | using System.Security.Cryptography;
2 | using System.Text;
3 |
4 | namespace Shadowsocks.Encryption
5 | {
6 | public abstract class EncryptorBase
7 | : IEncryptor
8 | {
9 | public const int MAX_INPUT_SIZE = 32768;
10 |
11 | protected EncryptorBase(string method, string password)
12 | {
13 | Method = method;
14 | Password = password;
15 | }
16 |
17 | protected string Method;
18 | protected string Password;
19 |
20 | protected byte[] GetPasswordHash()
21 | {
22 | byte[] inputBytes = Encoding.UTF8.GetBytes(Password);
23 | byte[] hash = MD5.Create().ComputeHash(inputBytes);
24 | return hash;
25 | }
26 |
27 | public abstract void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength);
28 |
29 | public abstract void Decrypt(byte[] buf, int length, byte[] outbuf, out int outlength);
30 |
31 | public abstract void Dispose();
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Encryption/EncryptorFactory.cs:
--------------------------------------------------------------------------------
1 |
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Reflection;
5 | namespace Shadowsocks.Encryption
6 | {
7 | public static class EncryptorFactory
8 | {
9 | private static Dictionary _registeredEncryptors;
10 |
11 | private static Type[] _constructorTypes = new Type[] { typeof(string), typeof(string) };
12 |
13 | static EncryptorFactory()
14 | {
15 | _registeredEncryptors = new Dictionary();
16 | foreach (string method in TableEncryptor.SupportedCiphers())
17 | {
18 | _registeredEncryptors.Add(method, typeof(TableEncryptor));
19 | }
20 | foreach (string method in PolarSSLEncryptor.SupportedCiphers())
21 | {
22 | _registeredEncryptors.Add(method, typeof(PolarSSLEncryptor));
23 | }
24 | foreach (string method in SodiumEncryptor.SupportedCiphers())
25 | {
26 | _registeredEncryptors.Add(method, typeof(SodiumEncryptor));
27 | }
28 | }
29 |
30 | public static IEncryptor GetEncryptor(string method, string password)
31 | {
32 | if (string.IsNullOrEmpty(method))
33 | {
34 | method = "table";
35 | }
36 | method = method.ToLowerInvariant();
37 | Type t = _registeredEncryptors[method];
38 | ConstructorInfo c = t.GetConstructor(_constructorTypes);
39 | IEncryptor result = (IEncryptor)c.Invoke(new object[] { method, password });
40 | return result;
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Encryption/IEncryptor.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace Shadowsocks.Encryption
6 | {
7 | public interface IEncryptor : IDisposable
8 | {
9 | void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength);
10 | void Decrypt(byte[] buf, int length, byte[] outbuf, out int outlength);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Encryption/IVEncryptor.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Security.Cryptography;
4 | using System.Text;
5 |
6 | namespace Shadowsocks.Encryption
7 | {
8 | public abstract class IVEncryptor
9 | : EncryptorBase
10 | {
11 | protected static byte[] tempbuf = new byte[MAX_INPUT_SIZE];
12 |
13 | protected Dictionary ciphers;
14 |
15 | private static readonly Dictionary CachedKeys = new Dictionary();
16 | protected byte[] _encryptIV;
17 | protected byte[] _decryptIV;
18 | protected bool _decryptIVReceived;
19 | protected bool _encryptIVSent;
20 | protected int _encryptIVOffset = 0;
21 | protected int _decryptIVOffset = 0;
22 | protected string _method;
23 | protected int _cipher;
24 | protected int[] _cipherInfo;
25 | protected byte[] _key;
26 | protected int keyLen;
27 | protected int ivLen;
28 |
29 | public IVEncryptor(string method, string password)
30 | : base(method, password)
31 | {
32 | InitKey(method, password);
33 | }
34 |
35 | protected abstract Dictionary getCiphers();
36 |
37 | protected void InitKey(string method, string password)
38 | {
39 | method = method.ToLower();
40 | _method = method;
41 | string k = method + ":" + password;
42 | ciphers = getCiphers();
43 | _cipherInfo = ciphers[_method];
44 | _cipher = _cipherInfo[2];
45 | if (_cipher == 0)
46 | {
47 | throw new Exception("method not found");
48 | }
49 | keyLen = ciphers[_method][0];
50 | ivLen = ciphers[_method][1];
51 | if (CachedKeys.ContainsKey(k))
52 | {
53 | _key = CachedKeys[k];
54 | }
55 | else
56 | {
57 | byte[] passbuf = Encoding.UTF8.GetBytes(password);
58 | _key = new byte[32];
59 | byte[] iv = new byte[16];
60 | bytesToKey(passbuf, _key);
61 | CachedKeys[k] = _key;
62 | }
63 | }
64 |
65 | protected void bytesToKey(byte[] password, byte[] key)
66 | {
67 | byte[] result = new byte[password.Length + 16];
68 | int i = 0;
69 | byte[] md5sum = null;
70 | while (i < key.Length)
71 | {
72 | MD5 md5 = MD5.Create();
73 | if (i == 0)
74 | {
75 | md5sum = md5.ComputeHash(password);
76 | }
77 | else
78 | {
79 | md5sum.CopyTo(result, 0);
80 | password.CopyTo(result, md5sum.Length);
81 | md5sum = md5.ComputeHash(result);
82 | }
83 | md5sum.CopyTo(key, i);
84 | i += md5sum.Length;
85 | }
86 | }
87 |
88 | protected static void randBytes(byte[] buf, int length)
89 | {
90 | byte[] temp = new byte[length];
91 | new Random().NextBytes(temp);
92 | temp.CopyTo(buf, 0);
93 | }
94 |
95 | protected virtual void initCipher(byte[] iv, bool isCipher)
96 | {
97 | if (ivLen > 0)
98 | {
99 | if (isCipher)
100 | {
101 | _encryptIV = new byte[ivLen];
102 | Array.Copy(iv, _encryptIV, ivLen);
103 | }
104 | else
105 | {
106 | _decryptIV = new byte[ivLen];
107 | Array.Copy(iv, _decryptIV, ivLen);
108 | }
109 | }
110 | }
111 |
112 | protected abstract void cipherUpdate(bool isCipher, int length, byte[] buf, byte[] outbuf);
113 |
114 | public override void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength)
115 | {
116 | if (!_encryptIVSent)
117 | {
118 | _encryptIVSent = true;
119 | randBytes(outbuf, ivLen);
120 | initCipher(outbuf, true);
121 | outlength = length + ivLen;
122 | lock (tempbuf)
123 | {
124 | cipherUpdate(true, length, buf, tempbuf);
125 | outlength = length + ivLen;
126 | Buffer.BlockCopy(tempbuf, 0, outbuf, ivLen, length);
127 | }
128 | }
129 | else
130 | {
131 | outlength = length;
132 | cipherUpdate(true, length, buf, outbuf);
133 | }
134 | }
135 |
136 | public override void Decrypt(byte[] buf, int length, byte[] outbuf, out int outlength)
137 | {
138 | if (!_decryptIVReceived)
139 | {
140 | _decryptIVReceived = true;
141 | initCipher(buf, false);
142 | outlength = length - ivLen;
143 | lock (tempbuf)
144 | {
145 | // C# could be multi-threaded
146 | Buffer.BlockCopy(buf, ivLen, tempbuf, 0, length - ivLen);
147 | cipherUpdate(false, length - ivLen, tempbuf, outbuf);
148 | }
149 | }
150 | else
151 | {
152 | outlength = length;
153 | cipherUpdate(false, length, buf, outbuf);
154 | }
155 | }
156 | }
157 | }
158 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Encryption/PolarSSL.cs:
--------------------------------------------------------------------------------
1 | using Shadowsocks.Controller;
2 | using Shadowsocks.Properties;
3 | using Shadowsocks.Util;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.IO;
7 | using System.Runtime.InteropServices;
8 | using System.Text;
9 |
10 | namespace Shadowsocks.Encryption
11 | {
12 | public class PolarSSL
13 | {
14 | const string DLLNAME = "libsscrypto";
15 |
16 | public const int AES_CTX_SIZE = 8 + 4 * 68;
17 | public const int AES_ENCRYPT = 1;
18 | public const int AES_DECRYPT = 0;
19 |
20 | static PolarSSL()
21 | {
22 | string tempPath = Utils.GetTempPath();
23 | string dllPath = tempPath + "/libsscrypto.dll";
24 | try
25 | {
26 | FileManager.UncompressFile(dllPath, Resources.libsscrypto_dll);
27 | }
28 | catch (IOException)
29 | {
30 | }
31 | catch (Exception e)
32 | {
33 | Console.WriteLine(e.ToString());
34 | }
35 | LoadLibrary(dllPath);
36 | }
37 |
38 | [DllImport("Kernel32.dll")]
39 | private static extern IntPtr LoadLibrary(string path);
40 |
41 | [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
42 | public extern static void aes_init(IntPtr ctx);
43 |
44 | [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
45 | public extern static void aes_free(IntPtr ctx);
46 |
47 | [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
48 | public extern static int aes_setkey_enc(IntPtr ctx, byte[] key, int keysize);
49 |
50 | [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
51 | public extern static int aes_crypt_cfb128(IntPtr ctx, int mode, int length, ref int iv_off, byte[] iv, byte[] input, byte[] output);
52 |
53 | public const int ARC4_CTX_SIZE = 264;
54 |
55 | [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
56 | public extern static void arc4_init(IntPtr ctx);
57 |
58 | [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
59 | public extern static void arc4_free(IntPtr ctx);
60 |
61 | [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
62 | public extern static void arc4_setup(IntPtr ctx, byte[] key, int keysize);
63 |
64 | [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
65 | public extern static int arc4_crypt(IntPtr ctx, int length, byte[] input, byte[] output);
66 |
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Encryption/Sodium.cs:
--------------------------------------------------------------------------------
1 | using Shadowsocks.Controller;
2 | using Shadowsocks.Properties;
3 | using Shadowsocks.Util;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.IO;
7 | using System.Runtime.InteropServices;
8 | using System.Text;
9 |
10 | namespace Shadowsocks.Encryption
11 | {
12 | public class Sodium
13 | {
14 | const string DLLNAME = "libsscrypto";
15 |
16 | static Sodium()
17 | {
18 | string tempPath = Utils.GetTempPath();
19 | string dllPath = tempPath + "/libsscrypto.dll";
20 | try
21 | {
22 | FileManager.UncompressFile(dllPath, Resources.libsscrypto_dll);
23 | LoadLibrary(dllPath);
24 | }
25 | catch (IOException)
26 | {
27 | }
28 | catch (Exception e)
29 | {
30 | Console.WriteLine(e.ToString());
31 | }
32 | LoadLibrary(dllPath);
33 | }
34 |
35 | [DllImport("Kernel32.dll")]
36 | private static extern IntPtr LoadLibrary(string path);
37 |
38 | [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
39 | public extern static void crypto_stream_salsa20_xor_ic(byte[] c, byte[] m, ulong mlen, byte[] n, ulong ic, byte[] k);
40 |
41 | [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
42 | public extern static void crypto_stream_chacha20_xor_ic(byte[] c, byte[] m, ulong mlen, byte[] n, ulong ic, byte[] k);
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Encryption/SodiumEncryptor.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.Threading;
5 |
6 | namespace Shadowsocks.Encryption
7 | {
8 | public class SodiumEncryptor
9 | : IVEncryptor, IDisposable
10 | {
11 | const int CIPHER_SALSA20 = 1;
12 | const int CIPHER_CHACHA20 = 2;
13 |
14 | const int SODIUM_BLOCK_SIZE = 64;
15 |
16 | static byte[] sodiumBuf = new byte[MAX_INPUT_SIZE + SODIUM_BLOCK_SIZE];
17 |
18 | protected int _encryptBytesRemaining;
19 | protected int _decryptBytesRemaining;
20 | protected ulong _encryptIC;
21 | protected ulong _decryptIC;
22 |
23 | public SodiumEncryptor(string method, string password)
24 | : base(method, password)
25 | {
26 | InitKey(method, password);
27 | }
28 |
29 | private static Dictionary _ciphers = new Dictionary {
30 | {"salsa20", new int[]{32, 8, CIPHER_SALSA20, PolarSSL.AES_CTX_SIZE}},
31 | {"chacha20", new int[]{32, 8, CIPHER_CHACHA20, PolarSSL.AES_CTX_SIZE}},
32 | };
33 |
34 | protected override Dictionary getCiphers()
35 | {
36 | return _ciphers;
37 | }
38 |
39 | public static List SupportedCiphers()
40 | {
41 | return new List(_ciphers.Keys);
42 | }
43 |
44 | protected override void cipherUpdate(bool isCipher, int length, byte[] buf, byte[] outbuf)
45 | {
46 | // TODO write a unidirection cipher so we don't have to if if if
47 | int bytesRemaining;
48 | ulong ic;
49 | byte[] iv;
50 |
51 | // I'm tired. just add a big lock
52 | // let's optimize for RAM instead of CPU
53 | lock(sodiumBuf)
54 | {
55 | if (isCipher)
56 | {
57 | bytesRemaining = _encryptBytesRemaining;
58 | ic = _encryptIC;
59 | iv = _encryptIV;
60 | }
61 | else
62 | {
63 | bytesRemaining = _decryptBytesRemaining;
64 | ic = _decryptIC;
65 | iv = _decryptIV;
66 | }
67 | int padding = bytesRemaining;
68 | Buffer.BlockCopy(buf, 0, sodiumBuf, padding, length);
69 |
70 | switch (_cipher)
71 | {
72 | case CIPHER_SALSA20:
73 | Sodium.crypto_stream_salsa20_xor_ic(sodiumBuf, sodiumBuf, (ulong)(padding + length), iv, ic, _key);
74 | break;
75 | case CIPHER_CHACHA20:
76 | Sodium.crypto_stream_chacha20_xor_ic(sodiumBuf, sodiumBuf, (ulong)(padding + length), iv, ic, _key);
77 | break;
78 | }
79 | Buffer.BlockCopy(sodiumBuf, padding, outbuf, 0, length);
80 | padding += length;
81 | ic += (ulong)padding / SODIUM_BLOCK_SIZE;
82 | bytesRemaining = padding % SODIUM_BLOCK_SIZE;
83 |
84 | if (isCipher)
85 | {
86 | _encryptBytesRemaining = bytesRemaining;
87 | _encryptIC = ic;
88 | }
89 | else
90 | {
91 | _decryptBytesRemaining = bytesRemaining;
92 | _decryptIC = ic;
93 | }
94 | }
95 | }
96 |
97 | public override void Dispose()
98 | {
99 | }
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Encryption/TableEncryptor.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace Shadowsocks.Encryption
5 | {
6 | public class TableEncryptor
7 | : EncryptorBase
8 | {
9 | public TableEncryptor(string method, string password)
10 | : base(method, password)
11 | {
12 | byte[] hash = GetPasswordHash();
13 | // TODO endian
14 | ulong a = BitConverter.ToUInt64(hash, 0);
15 | for (int i = 0; i < 256; i++)
16 | {
17 | _encryptTable[i] = (byte)i;
18 | }
19 | for (int i = 1; i < 1024; i++)
20 | {
21 | _encryptTable = MergeSort(_encryptTable, a, i);
22 | }
23 | for (int i = 0; i < 256; i++)
24 | {
25 | _decryptTable[_encryptTable[i]] = (byte)i;
26 | }
27 | }
28 |
29 | public static List SupportedCiphers()
30 | {
31 | return new List(new string[]{"table"});
32 | }
33 |
34 | public override void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength)
35 | {
36 | byte[] result = new byte[length];
37 | for (int i = 0; i < length; i++)
38 | {
39 | outbuf[i] = _encryptTable[buf[i]];
40 | }
41 | outlength = length;
42 | }
43 |
44 | public override void Decrypt(byte[] buf, int length, byte[] outbuf, out int outlength)
45 | {
46 | byte[] result = new byte[length];
47 | for (int i = 0; i < length; i++)
48 | {
49 | outbuf[i] = _decryptTable[buf[i]];
50 | }
51 | outlength = length;
52 | }
53 |
54 | private readonly byte[] _encryptTable = new byte[256];
55 | private readonly byte[] _decryptTable = new byte[256];
56 |
57 | private static long Compare(byte x, byte y, ulong a, int i)
58 | {
59 | return (long)(a % (ulong)(x + i)) - (long)(a % (ulong)(y + i));
60 | }
61 |
62 | private byte[] MergeSort(byte[] array, ulong a, int j)
63 | {
64 | if (array.Length == 1)
65 | {
66 | return array;
67 | }
68 | int middle = array.Length / 2;
69 | byte[] left = new byte[middle];
70 | for (int i = 0; i < middle; i++)
71 | {
72 | left[i] = array[i];
73 | }
74 | byte[] right = new byte[array.Length - middle];
75 | for (int i = 0; i < array.Length - middle; i++)
76 | {
77 | right[i] = array[i + middle];
78 | }
79 | left = MergeSort(left, a, j);
80 | right = MergeSort(right, a, j);
81 |
82 | int leftptr = 0;
83 | int rightptr = 0;
84 |
85 | byte[] sorted = new byte[array.Length];
86 | for (int k = 0; k < array.Length; k++)
87 | {
88 | if (rightptr == right.Length || ((leftptr < left.Length) && (Compare(left[leftptr], right[rightptr], a, j) <= 0)))
89 | {
90 | sorted[k] = left[leftptr];
91 | leftptr++;
92 | }
93 | else if (leftptr == left.Length || ((rightptr < right.Length) && (Compare(right[rightptr], left[leftptr], a, j)) <= 0))
94 | {
95 | sorted[k] = right[rightptr];
96 | rightptr++;
97 | }
98 | }
99 | return sorted;
100 | }
101 |
102 | public override void Dispose()
103 | {
104 | }
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Model/Configuration.cs:
--------------------------------------------------------------------------------
1 | using Shadowsocks.Controller;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.IO;
5 | using System.Text;
6 | using System.Windows.Forms;
7 |
8 | namespace Shadowsocks.Model
9 | {
10 | [Serializable]
11 | public class Configuration
12 | {
13 | public List configs;
14 |
15 | // when strategy is set, index is ignored
16 | public string strategy;
17 | public int index;
18 | public bool global;
19 | public bool enabled;
20 | public bool shareOverLan;
21 | public bool isDefault;
22 | public int localPort;
23 | public string pacUrl;
24 | public bool useOnlinePac;
25 | public bool availabilityStatistics;
26 |
27 | private static string CONFIG_FILE = "gui-config.json";
28 |
29 | public Server GetCurrentServer()
30 | {
31 | if (index >= 0 && index < configs.Count)
32 | {
33 | return configs[index];
34 | }
35 | else
36 | {
37 | return GetDefaultServer();
38 | }
39 | }
40 |
41 | public static void CheckServer(Server server)
42 | {
43 | CheckPort(server.server_port);
44 | CheckPassword(server.password);
45 | CheckServer(server.server);
46 | }
47 |
48 | public static Configuration Load()
49 | {
50 | try
51 | {
52 | string configContent = File.ReadAllText(CONFIG_FILE);
53 | Configuration config = SimpleJson.SimpleJson.DeserializeObject(configContent, new JsonSerializerStrategy());
54 | config.isDefault = false;
55 | if (config.localPort == 0)
56 | {
57 | config.localPort = 1080;
58 | }
59 | if (config.index == -1)
60 | {
61 | if (config.strategy == null)
62 | {
63 | config.index = 0;
64 | }
65 | }
66 | return config;
67 | }
68 | catch (Exception e)
69 | {
70 | if (!(e is FileNotFoundException))
71 | {
72 | Console.WriteLine(e);
73 | }
74 | return new Configuration
75 | {
76 | index = 0,
77 | isDefault = true,
78 | localPort = 1080,
79 | configs = new List()
80 | {
81 | GetDefaultServer()
82 | }
83 | };
84 | }
85 | }
86 |
87 | public static void Save(Configuration config)
88 | {
89 | if (config.index >= config.configs.Count)
90 | {
91 | config.index = config.configs.Count - 1;
92 | }
93 | if (config.index < -1)
94 | {
95 | config.index = -1;
96 | }
97 | if (config.index == -1)
98 | {
99 | if (config.strategy == null)
100 | {
101 | config.index = 0;
102 | }
103 | }
104 | config.isDefault = false;
105 | try
106 | {
107 | using (StreamWriter sw = new StreamWriter(File.Open(CONFIG_FILE, FileMode.Create)))
108 | {
109 | string jsonString = SimpleJson.SimpleJson.SerializeObject(config);
110 | sw.Write(jsonString);
111 | sw.Flush();
112 | }
113 | }
114 | catch (IOException e)
115 | {
116 | Console.Error.WriteLine(e);
117 | }
118 | }
119 |
120 | public static Server GetDefaultServer()
121 | {
122 | return new Server();
123 | }
124 |
125 | private static void Assert(bool condition)
126 | {
127 | if (!condition)
128 | {
129 | throw new Exception(I18N.GetString("assertion failure"));
130 | }
131 | }
132 |
133 | public static void CheckPort(int port)
134 | {
135 | if (port <= 0 || port > 65535)
136 | {
137 | throw new ArgumentException(I18N.GetString("Port out of range"));
138 | }
139 | }
140 |
141 | public static void CheckLocalPort(int port)
142 | {
143 | CheckPort(port);
144 | if (port == 8123)
145 | {
146 | throw new ArgumentException(I18N.GetString("Port can't be 8123"));
147 | }
148 | }
149 |
150 | private static void CheckPassword(string password)
151 | {
152 | if (string.IsNullOrEmpty(password))
153 | {
154 | throw new ArgumentException(I18N.GetString("Password can not be blank"));
155 | }
156 | }
157 |
158 | private static void CheckServer(string server)
159 | {
160 | if (string.IsNullOrEmpty(server))
161 | {
162 | throw new ArgumentException(I18N.GetString("Server IP can not be blank"));
163 | }
164 | }
165 |
166 | private class JsonSerializerStrategy : SimpleJson.PocoJsonSerializerStrategy
167 | {
168 | // convert string to int
169 | public override object DeserializeObject(object value, Type type)
170 | {
171 | if (type == typeof(Int32) && value.GetType() == typeof(string))
172 | {
173 | return Int32.Parse(value.ToString());
174 | }
175 | return base.DeserializeObject(value, type);
176 | }
177 | }
178 | }
179 | }
180 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Model/Server.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.IO;
5 | using System.Diagnostics;
6 | using SimpleJson;
7 | using Shadowsocks.Controller;
8 | using System.Text.RegularExpressions;
9 |
10 | namespace Shadowsocks.Model
11 | {
12 | [Serializable]
13 | public class Server
14 | {
15 | public string server;
16 | public int server_port;
17 | public string password;
18 | public string method;
19 | public string remarks;
20 |
21 | public override int GetHashCode()
22 | {
23 | return server.GetHashCode() ^ server_port;
24 | }
25 |
26 | public override bool Equals(object obj)
27 | {
28 | Server o2 = (Server)obj;
29 | return this.server == o2.server && this.server_port == o2.server_port;
30 | }
31 |
32 | public string FriendlyName()
33 | {
34 | if (string.IsNullOrEmpty(server))
35 | {
36 | return I18N.GetString("New server");
37 | }
38 | if (string.IsNullOrEmpty(remarks))
39 | {
40 | return server + ":" + server_port;
41 | }
42 | else
43 | {
44 | return remarks + " (" + server + ":" + server_port + ")";
45 | }
46 | }
47 |
48 | public Server()
49 | {
50 | this.server = "";
51 | this.server_port = 8388;
52 | this.method = "aes-256-cfb";
53 | this.password = "";
54 | this.remarks = "";
55 | }
56 |
57 | public Server(string ssURL) : this()
58 | {
59 | string[] r1 = Regex.Split(ssURL, "ss://", RegexOptions.IgnoreCase);
60 | string base64 = r1[1].ToString();
61 | byte[] bytes = null;
62 | for (var i = 0; i < 3; i++)
63 | {
64 | try
65 | {
66 | bytes = System.Convert.FromBase64String(base64);
67 | }
68 | catch (FormatException)
69 | {
70 | base64 += "=";
71 | }
72 | }
73 | if (bytes == null)
74 | {
75 | throw new FormatException();
76 | }
77 | try
78 | {
79 | string data = Encoding.UTF8.GetString(bytes);
80 | int indexLastAt = data.LastIndexOf('@');
81 |
82 | string afterAt = data.Substring(indexLastAt + 1);
83 | int indexLastColon = afterAt.LastIndexOf(':');
84 | this.server_port = int.Parse(afterAt.Substring(indexLastColon + 1));
85 | this.server = afterAt.Substring(0, indexLastColon);
86 |
87 | string beforeAt = data.Substring(0, indexLastAt);
88 | string[] parts = beforeAt.Split(new[] { ':' });
89 | this.method = parts[0];
90 | this.password = parts[1];
91 | }
92 | catch (IndexOutOfRangeException)
93 | {
94 | throw new FormatException();
95 | }
96 | }
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Program.cs:
--------------------------------------------------------------------------------
1 | using Shadowsocks.Controller;
2 | using Shadowsocks.Properties;
3 | using Shadowsocks.View;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Diagnostics;
7 | using System.IO;
8 | using System.Threading;
9 | using System.Windows.Forms;
10 |
11 | namespace Shadowsocks
12 | {
13 | static class Program
14 | {
15 | ///
16 | /// 应用程序的主入口点。
17 | ///
18 | [STAThread]
19 | static void Main()
20 | {
21 | Util.Utils.ReleaseMemory(true);
22 | using (Mutex mutex = new Mutex(false, "Global\\Shadowsocks_" + Application.StartupPath.GetHashCode()))
23 | {
24 | Application.EnableVisualStyles();
25 | Application.SetCompatibleTextRenderingDefault(false);
26 |
27 | if (!mutex.WaitOne(0, false))
28 | {
29 | Process[] oldProcesses = Process.GetProcessesByName("Shadowsocks");
30 | if (oldProcesses.Length > 0)
31 | {
32 | Process oldProcess = oldProcesses[0];
33 | }
34 | MessageBox.Show(I18N.GetString("Find Shadowsocks icon in your notify tray.") + "\n" +
35 | I18N.GetString("If you want to start multiple Shadowsocks, make a copy in another directory."),
36 | I18N.GetString("Shadowsocks is already running."));
37 | return;
38 | }
39 | Directory.SetCurrentDirectory(Application.StartupPath);
40 | #if !DEBUG
41 | Logging.OpenLogFile();
42 | #endif
43 | ShadowsocksController controller = new ShadowsocksController();
44 |
45 | MenuViewController viewController = new MenuViewController(controller);
46 |
47 | controller.Start();
48 |
49 | Application.Run();
50 | }
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using Shadowsocks.Controller;
2 | using System.Reflection;
3 | using System.Runtime.CompilerServices;
4 | using System.Runtime.InteropServices;
5 |
6 | // 有关程序集的常规信息通过下列属性集
7 | // 控制。更改这些属性值可修改
8 | // 与程序集关联的信息。
9 | [assembly: AssemblyTitle("Shadowsocks")]
10 | [assembly: AssemblyDescription("")]
11 | [assembly: AssemblyConfiguration("")]
12 | [assembly: AssemblyCompany("")]
13 | [assembly: AssemblyProduct("Shadowsocks")]
14 | [assembly: AssemblyCopyright("Copyright © clowwindy 2015")]
15 | [assembly: AssemblyTrademark("")]
16 | [assembly: AssemblyCulture("")]
17 |
18 | // 将 ComVisible 设置为 false 使此程序集中的类型
19 | // 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型,
20 | // 则将该类型上的 ComVisible 属性设置为 true。
21 | [assembly: ComVisible(false)]
22 |
23 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
24 | [assembly: Guid("f8334709-4309-436a-8bbd-6165dcf4a660")]
25 |
26 | // 程序集的版本信息由下面四个值组成:
27 | //
28 | // 主版本
29 | // 次版本
30 | // 内部版本号
31 | // 修订号
32 | //
33 | // 可以指定所有这些值,也可以使用“内部版本号”和“修订号”的默认值,
34 | // 方法是按如下所示使用“*”:
35 | // [assembly: AssemblyVersion("1.0.*")]
36 | [assembly: AssemblyVersion(UpdateChecker.Version)]
37 | // [assembly: AssemblyFileVersion("2.0.0")]
38 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Resources/ss16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Long-live-shadowsocks/shadowsocks-windows/b07a9ef3b06a5fd9646aa1e502319afdb6f578c8/shadowsocks-csharp/Resources/ss16.png
--------------------------------------------------------------------------------
/shadowsocks-csharp/Resources/ss20.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Long-live-shadowsocks/shadowsocks-windows/b07a9ef3b06a5fd9646aa1e502319afdb6f578c8/shadowsocks-csharp/Resources/ss20.png
--------------------------------------------------------------------------------
/shadowsocks-csharp/Resources/ss24.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Long-live-shadowsocks/shadowsocks-windows/b07a9ef3b06a5fd9646aa1e502319afdb6f578c8/shadowsocks-csharp/Resources/ss24.png
--------------------------------------------------------------------------------
/shadowsocks-csharp/Resources/ssw128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Long-live-shadowsocks/shadowsocks-windows/b07a9ef3b06a5fd9646aa1e502319afdb6f578c8/shadowsocks-csharp/Resources/ssw128.png
--------------------------------------------------------------------------------
/shadowsocks-csharp/Util/Util.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 | using System.IO;
5 | using System.IO.Compression;
6 | using System.Runtime.InteropServices;
7 | using System.Text;
8 | using System.Windows.Forms;
9 |
10 | namespace Shadowsocks.Util
11 | {
12 | public class Utils
13 | {
14 | // return path to store temporary files
15 | public static string GetTempPath()
16 | {
17 | if (File.Exists(Application.StartupPath + "\\shadowsocks_portable_mode.txt"))
18 | {
19 | try
20 | {
21 | Directory.CreateDirectory(Application.StartupPath + "\\temp");
22 | } catch (Exception e)
23 | {
24 | Console.WriteLine(e);
25 | }
26 | // don't use "/", it will fail when we call explorer /select xxx/temp\xxx.log
27 | return Application.StartupPath + "\\temp";
28 | }
29 | return Path.GetTempPath();
30 | }
31 |
32 | public static void ReleaseMemory(bool removePages)
33 | {
34 | // release any unused pages
35 | // making the numbers look good in task manager
36 | // this is totally nonsense in programming
37 | // but good for those users who care
38 | // making them happier with their everyday life
39 | // which is part of user experience
40 | GC.Collect(GC.MaxGeneration);
41 | GC.WaitForPendingFinalizers();
42 | if (removePages)
43 | {
44 | // as some users have pointed out
45 | // removing pages from working set will cause some IO
46 | // which lowered user experience for another group of users
47 | //
48 | // so we do 2 more things here to satisfy them:
49 | // 1. only remove pages once when configuration is changed
50 | // 2. add more comments here to tell users that calling
51 | // this function will not be more frequent than
52 | // IM apps writing chat logs, or web browsers writing cache files
53 | // if they're so concerned about their disk, they should
54 | // uninstall all IM apps and web browsers
55 | //
56 | // please open an issue if you're worried about anything else in your computer
57 | // no matter it's GPU performance, monitor contrast, audio fidelity
58 | // or anything else in the task manager
59 | // we'll do as much as we can to help you
60 | //
61 | // just kidding
62 | SetProcessWorkingSetSize(Process.GetCurrentProcess().Handle,
63 | (UIntPtr)0xFFFFFFFF, (UIntPtr)0xFFFFFFFF);
64 | }
65 | }
66 |
67 | public static string UnGzip(byte[] buf)
68 | {
69 | byte[] buffer = new byte[1024];
70 | int n;
71 | using (MemoryStream sb = new MemoryStream())
72 | {
73 | using (GZipStream input = new GZipStream(new MemoryStream(buf),
74 | CompressionMode.Decompress, false))
75 | {
76 | while ((n = input.Read(buffer, 0, buffer.Length)) > 0)
77 | {
78 | sb.Write(buffer, 0, n);
79 | }
80 | }
81 | return System.Text.Encoding.UTF8.GetString(sb.ToArray());
82 | }
83 | }
84 |
85 | [DllImport("kernel32.dll")]
86 | [return: MarshalAs(UnmanagedType.Bool)]
87 | private static extern bool SetProcessWorkingSetSize(IntPtr process,
88 | UIntPtr minimumWorkingSetSize, UIntPtr maximumWorkingSetSize);
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/View/ConfigForm.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/View/LogForm.cs:
--------------------------------------------------------------------------------
1 | using Shadowsocks.Controller;
2 | using Shadowsocks.Properties;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.ComponentModel;
6 | using System.Data;
7 | using System.Drawing;
8 | using System.IO;
9 | using System.Linq;
10 | using System.Text;
11 | using System.Windows.Forms;
12 |
13 | namespace Shadowsocks.View
14 | {
15 | public partial class LogForm : Form
16 | {
17 | long lastOffset;
18 | string filename;
19 | Timer timer;
20 | const int BACK_OFFSET = 65536;
21 |
22 | public LogForm(string filename)
23 | {
24 | this.filename = filename;
25 | InitializeComponent();
26 | this.Icon = Icon.FromHandle(Resources.ssw128.GetHicon());
27 |
28 | UpdateTexts();
29 | }
30 |
31 | private void UpdateTexts()
32 | {
33 | FileMenuItem.Text = I18N.GetString("&File");
34 | OpenLocationMenuItem.Text = I18N.GetString("&Open Location");
35 | ExitMenuItem.Text = I18N.GetString("E&xit");
36 | CleanLogsButton.Text = I18N.GetString("&Clean logs");
37 | ChangeFontButton.Text = I18N.GetString("&Font");
38 | WrapTextCheckBox.Text = I18N.GetString("&Wrap text");
39 | TopMostCheckBox.Text = I18N.GetString("&Top most");
40 | this.Text = I18N.GetString("Log Viewer");
41 | }
42 |
43 | private void Timer_Tick(object sender, EventArgs e)
44 | {
45 | UpdateContent();
46 | }
47 |
48 | private void InitContent()
49 | {
50 | using (StreamReader reader = new StreamReader(new FileStream(filename,
51 | FileMode.Open, FileAccess.Read, FileShare.ReadWrite)))
52 | {
53 | if (reader.BaseStream.Length > BACK_OFFSET)
54 | {
55 | reader.BaseStream.Seek(-BACK_OFFSET, SeekOrigin.End);
56 | reader.ReadLine();
57 | }
58 |
59 | string line = "";
60 | while ((line = reader.ReadLine()) != null)
61 | LogMessageTextBox.AppendText(line + "\r\n");
62 |
63 | LogMessageTextBox.ScrollToCaret();
64 |
65 | lastOffset = reader.BaseStream.Position;
66 | }
67 | }
68 |
69 | private void UpdateContent()
70 | {
71 | using (StreamReader reader = new StreamReader(new FileStream(filename,
72 | FileMode.Open, FileAccess.Read, FileShare.ReadWrite)))
73 | {
74 | reader.BaseStream.Seek(lastOffset, SeekOrigin.Begin);
75 |
76 | string line = "";
77 | bool changed = false;
78 | while ((line = reader.ReadLine()) != null)
79 | {
80 | changed = true;
81 | LogMessageTextBox.AppendText(line + "\r\n");
82 | }
83 |
84 | if (changed)
85 | {
86 | LogMessageTextBox.ScrollToCaret();
87 | }
88 |
89 | lastOffset = reader.BaseStream.Position;
90 | }
91 | }
92 |
93 | private void LogForm_Load(object sender, EventArgs e)
94 | {
95 | InitContent();
96 | timer = new Timer();
97 | timer.Interval = 300;
98 | timer.Tick += Timer_Tick;
99 | timer.Start();
100 | }
101 |
102 | private void LogForm_FormClosing(object sender, FormClosingEventArgs e)
103 | {
104 | timer.Stop();
105 | }
106 |
107 | private void OpenLocationMenuItem_Click(object sender, EventArgs e)
108 | {
109 | string argument = "/select, \"" + filename + "\"";
110 | Console.WriteLine(argument);
111 | System.Diagnostics.Process.Start("explorer.exe", argument);
112 | }
113 |
114 | private void ExitMenuItem_Click(object sender, EventArgs e)
115 | {
116 | this.Close();
117 | }
118 |
119 | private void LogForm_Shown(object sender, EventArgs e)
120 | {
121 | LogMessageTextBox.ScrollToCaret();
122 | }
123 |
124 | private void WrapTextCheckBox_CheckedChanged(object sender, EventArgs e)
125 | {
126 | LogMessageTextBox.WordWrap = WrapTextCheckBox.Checked;
127 | LogMessageTextBox.ScrollToCaret();
128 | }
129 |
130 | private void CleanLogsButton_Click(object sender, EventArgs e)
131 | {
132 | LogMessageTextBox.Clear();
133 | }
134 |
135 | private void ChangeFontButton_Click(object sender, EventArgs e)
136 | {
137 | FontDialog fd = new FontDialog();
138 | fd.Font = LogMessageTextBox.Font;
139 | if (fd.ShowDialog() == DialogResult.OK)
140 | {
141 | LogMessageTextBox.Font = fd.Font;
142 | }
143 | }
144 |
145 | private void TopMostCheckBox_CheckedChanged(object sender, EventArgs e)
146 | {
147 | this.TopMost = TopMostCheckBox.Checked;
148 | }
149 | }
150 | }
151 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/View/LogForm.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | 17, 17
122 |
123 |
124 | 172, 17
125 |
126 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/View/QRCodeForm.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace Shadowsocks.View
2 | {
3 | partial class QRCodeForm
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.pictureBox1 = new System.Windows.Forms.PictureBox();
32 | this.listBox1 = new System.Windows.Forms.ListBox();
33 | ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
34 | this.SuspendLayout();
35 | //
36 | // pictureBox1
37 | //
38 | this.pictureBox1.Location = new System.Drawing.Point(10, 10);
39 | this.pictureBox1.Margin = new System.Windows.Forms.Padding(0);
40 | this.pictureBox1.Name = "pictureBox1";
41 | this.pictureBox1.Size = new System.Drawing.Size(210, 210);
42 | this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
43 | this.pictureBox1.TabIndex = 1;
44 | this.pictureBox1.TabStop = false;
45 | //
46 | // listBox1
47 | //
48 | this.listBox1.DisplayMember = "Value";
49 | this.listBox1.FormattingEnabled = true;
50 | this.listBox1.ItemHeight = 12;
51 | this.listBox1.Location = new System.Drawing.Point(224, 10);
52 | this.listBox1.Name = "listBox1";
53 | this.listBox1.ScrollAlwaysVisible = true;
54 | this.listBox1.Size = new System.Drawing.Size(227, 208);
55 | this.listBox1.TabIndex = 2;
56 | this.listBox1.ValueMember = "Key";
57 | this.listBox1.SelectedIndexChanged += new System.EventHandler(this.listBox1_SelectedIndexChanged);
58 | //
59 | // QRCodeForm
60 | //
61 | this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
62 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
63 | this.AutoSize = true;
64 | this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
65 | this.BackColor = System.Drawing.Color.White;
66 | this.ClientSize = new System.Drawing.Size(457, 228);
67 | this.Controls.Add(this.listBox1);
68 | this.Controls.Add(this.pictureBox1);
69 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
70 | this.MaximizeBox = false;
71 | this.MinimizeBox = false;
72 | this.Name = "QRCodeForm";
73 | this.Padding = new System.Windows.Forms.Padding(10);
74 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
75 | this.Text = "QRCode";
76 | this.Load += new System.EventHandler(this.QRCodeForm_Load);
77 | ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
78 | this.ResumeLayout(false);
79 |
80 | }
81 |
82 | #endregion
83 |
84 | private System.Windows.Forms.PictureBox pictureBox1;
85 | private System.Windows.Forms.ListBox listBox1;
86 | }
87 | }
--------------------------------------------------------------------------------
/shadowsocks-csharp/View/QRCodeForm.cs:
--------------------------------------------------------------------------------
1 | using ZXing.QrCode.Internal;
2 | using Shadowsocks.Controller;
3 | using Shadowsocks.Properties;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.ComponentModel;
7 | using System.Data;
8 | using System.Drawing;
9 | using System.IO;
10 | using System.IO.Compression;
11 | using System.Linq;
12 | using System.Text;
13 | using System.Windows.Forms;
14 | using Shadowsocks.Model;
15 |
16 | namespace Shadowsocks.View
17 | {
18 | public partial class QRCodeForm : Form
19 | {
20 | private string code;
21 |
22 | public QRCodeForm(string code)
23 | {
24 | this.code = code;
25 | InitializeComponent();
26 | this.Icon = Icon.FromHandle(Resources.ssw128.GetHicon());
27 | this.Text = I18N.GetString("QRCode");
28 | }
29 |
30 | private void GenQR(string ssconfig)
31 | {
32 | string qrText = ssconfig;
33 | QRCode code = ZXing.QrCode.Internal.Encoder.encode(qrText, ErrorCorrectionLevel.M);
34 | ByteMatrix m = code.Matrix;
35 | int blockSize = Math.Max(pictureBox1.Height/m.Height, 1);
36 | Bitmap drawArea = new Bitmap((m.Width*blockSize), (m.Height*blockSize));
37 | using (Graphics g = Graphics.FromImage(drawArea))
38 | {
39 | g.Clear(Color.White);
40 | using (Brush b = new SolidBrush(Color.Black))
41 | {
42 | for (int row = 0; row < m.Width; row++)
43 | {
44 | for (int col = 0; col < m.Height; col++)
45 | {
46 | if (m[row, col] != 0)
47 | {
48 | g.FillRectangle(b, blockSize*row, blockSize*col, blockSize, blockSize);
49 | }
50 | }
51 | }
52 | }
53 | }
54 | pictureBox1.Image = drawArea;
55 | }
56 |
57 | private void QRCodeForm_Load(object sender, EventArgs e)
58 | {
59 | var servers = Configuration.Load();
60 | var serverDatas = servers.configs.Select(
61 | server =>
62 | new KeyValuePair(ShadowsocksController.GetQRCode(server), server.FriendlyName())
63 | ).ToList();
64 | listBox1.DataSource = serverDatas;
65 |
66 | var selectIndex = serverDatas.FindIndex(serverData => serverData.Key.StartsWith(code));
67 | if (selectIndex >= 0) listBox1.SetSelected(selectIndex, true);
68 | }
69 |
70 | private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
71 | {
72 | GenQR((sender as ListBox)?.SelectedValue.ToString());
73 | }
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/View/QRCodeForm.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/app.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/app.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | true
14 |
15 |
16 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/shadowsocks.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Long-live-shadowsocks/shadowsocks-windows/b07a9ef3b06a5fd9646aa1e502319afdb6f578c8/shadowsocks-csharp/shadowsocks.ico
--------------------------------------------------------------------------------
/test/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("test")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("test")]
13 | [assembly: AssemblyCopyright("Copyright © 2015")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("f74e87ac-7e3a-444b-a1d9-8b91a674c60f")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/test/test.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | {45913187-0685-4903-B250-DCEF0479CD86}
7 | Library
8 | Properties
9 | test
10 | test
11 | v4.5
12 | 512
13 | {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
14 | 10.0
15 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
16 | $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages
17 | False
18 | UnitTest
19 |
20 |
21 |
22 | bin\x86\Debug\
23 | x86
24 |
25 |
26 | bin\x86\Release\
27 | x86
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 | {8c02d2f7-7cdb-4d55-9f25-cd03ef4aa062}
54 | shadowsocks-csharp
55 |
56 |
57 |
58 |
59 |
60 |
61 | False
62 |
63 |
64 | False
65 |
66 |
67 | False
68 |
69 |
70 | False
71 |
72 |
73 |
74 |
75 |
76 |
77 |
84 |
--------------------------------------------------------------------------------