diff --git a/MixDecrypt/MixDecrypt.cpp b/MixDecrypt/MixDecrypt.cpp deleted file mode 100644 index 6af0677fcb..0000000000 --- a/MixDecrypt/MixDecrypt.cpp +++ /dev/null @@ -1,4 +0,0 @@ -// This is the main DLL file. - -#include "MixDecrypt.h" - diff --git a/MixDecrypt/MixDecrypt.h b/MixDecrypt/MixDecrypt.h deleted file mode 100644 index fd95877bdf..0000000000 --- a/MixDecrypt/MixDecrypt.h +++ /dev/null @@ -1,26 +0,0 @@ -// MixDecrypt.h -#pragma once - -#pragma unmanaged -#include "mix_decode.h" -#pragma managed - -using namespace System; - -namespace MixDecrypt { - - public ref class MixDecrypt - { - public: - static array^ BlowfishKey( array^ src ) - { - array^ dest = gcnew array( 56 ); - pin_ptr s = &src[0]; - pin_ptr d = &dest[0]; - - get_blowfish_key( s, d ); - - return dest; - } - }; -} diff --git a/MixDecrypt/MixDecrypt.vcproj b/MixDecrypt/MixDecrypt.vcproj deleted file mode 100644 index 32c0e614e6..0000000000 --- a/MixDecrypt/MixDecrypt.vcproj +++ /dev/null @@ -1,199 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/MixDecrypt/mix_decode.h b/MixDecrypt/mix_decode.h deleted file mode 100644 index 61129f35c4..0000000000 --- a/MixDecrypt/mix_decode.h +++ /dev/null @@ -1,428 +0,0 @@ -#include - -const static char* pubkey_str = "AihRvNoIbTn85FZRYNZRcT+i6KpU+maCsEqr3Q5q+LDB5tH7Tz2qQ38V"; - -const static char char2num[] = { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, - -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, - -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; - -typedef unsigned int dword; -typedef unsigned short word; -typedef unsigned char byte; - -typedef dword bignum4[4]; -typedef dword bignum[64]; -typedef dword bignum130[130]; - -static struct -{ - bignum key1; - bignum key2; - dword len; -} pubkey; -static bignum glob1; -static dword glob1_bitlen, glob1_len_x2; -static bignum130 glob2; -static bignum4 glob1_hi, glob1_hi_inv; -static dword glob1_hi_bitlen; -static dword glob1_hi_inv_lo, glob1_hi_inv_hi; - -static void init_bignum(bignum n, dword val, dword len) -{ - memset((void *)n, 0, len * 4); - n[0] = val; -} - -static void move_key_to_big(bignum n, char *key, dword klen, dword blen) -{ - dword sign; - unsigned i; - - if (key[0] & 0x80) sign = 0xff; - else sign = 0; - - for (i = blen*4; i > klen; i--) - ((char *)n)[i-1] = sign; - for (; i > 0; i--) - ((char *)n)[i-1] = key[klen-i]; -} - -static void key_to_bignum(bignum n, char *key, dword len) -{ - dword keylen; - int i; - - if (key[0] != 2) return; - key++; - - if (key[0] & 0x80) - { - keylen = 0; - for (i = 0; i < (key[0] & 0x7f); i++) keylen = (keylen << 8) | key[i+1]; - key += (key[0] & 0x7f) + 1; - } - else - { - keylen = key[0]; - key++; - } - if (keylen <= len*4) - move_key_to_big(n, key, keylen, len); -} - -static dword len_bignum(bignum n, dword len) -{ - int i; - i = len-1; - while ((i >= 0) && (n[i] == 0)) i--; - return i+1; -} - -static dword bitlen_bignum(bignum n, dword len) -{ - dword ddlen, bitlen, mask; - ddlen = len_bignum(n, len); - if (ddlen == 0) return 0; - bitlen = ddlen * 32; - mask = 0x80000000; - while ((mask & n[ddlen-1]) == 0) { - mask >>= 1; - bitlen--; - } - return bitlen; -} - -static void init_pubkey() -{ - dword i, i2, tmp; - char keytmp[256]; - - init_bignum(pubkey.key2, 0x10001, 64); - - i = 0; - i2 = 0; - while (i < strlen(pubkey_str)) - { - tmp = char2num[pubkey_str[i++]]; - tmp <<= 6; tmp |= char2num[pubkey_str[i++]]; - tmp <<= 6; tmp |= char2num[pubkey_str[i++]]; - tmp <<= 6; tmp |= char2num[pubkey_str[i++]]; - keytmp[i2++] = (tmp >> 16) & 0xff; - keytmp[i2++] = (tmp >> 8) & 0xff; - keytmp[i2++] = tmp & 0xff; - } - key_to_bignum(pubkey.key1, keytmp, 64); - pubkey.len = bitlen_bignum(pubkey.key1, 64) - 1; -} - -static dword len_predata() -{ - dword a = (pubkey.len - 1) / 8; - return (55 / a + 1) * (a + 1); -} - -static long int cmp_bignum(bignum n1, bignum n2, dword len) -{ - n1 += len-1; - n2 += len-1; - while (len > 0) { - if (*n1 < *n2) return -1; - if (*n1 > *n2) return 1; - n1--; - n2--; - len--; - } - return 0; -} - -static void mov_bignum(bignum dest, bignum src, dword len) -{ - memmove(dest, src, len*4); -} - -static void shr_bignum(bignum n, dword bits, unsigned long int len) -{ - dword i, i2; - - i2 = bits / 32; - if (i2 > 0) { - for (i = 0; i < len - i2; i++) n[i] = n[i + i2]; - for (; i < len; i++) n[i] = 0; - bits = bits % 32; - } - if (bits == 0) return; - for (i = 0; i < len - 1; i++) n[i] = (n[i] >> bits) | (n[i + 1] << (32 - -bits)); - n[i] = n[i] >> bits; -} - -static void shl_bignum(bignum n, dword bits, dword len) -{ - dword i, i2; - - i2 = bits / 32; - if (i2 > 0) { - for (i = len - 1; i > i2; i--) n[i] = n[i - i2]; - for (; i > 0; i--) n[i] = 0; - bits = bits % 32; - } - if (bits == 0) return; - for (i = len - 1; i > 0; i--) n[i] = (n[i] << bits) | (n[i - 1] >> (32 - -bits)); - n[0] <<= bits; -} - -static dword sub_bignum(bignum dest, bignum src1, bignum src2, dword carry, dword len) -{ - dword i1, i2; - - len += len; - while (--len != -1) { - i1 = *(word *)src1; - i2 = *(word *)src2; - *(word *)dest = i1 - i2 - carry; - src1 = (dword *)(((word *)src1) + 1); - src2 = (dword *)(((word *)src2) + 1); - dest = (dword *)(((word *)dest) + 1); - if ((i1 - i2 - carry) & 0x10000) carry = 1; else carry = 0; - } - return carry; -} - -static void inv_bignum(bignum n1, bignum n2, dword len) -{ - bignum n_tmp; - dword n2_bytelen, bit; - long int n2_bitlen; - - init_bignum(n_tmp, 0, len); - init_bignum(n1, 0, len); - n2_bitlen = bitlen_bignum(n2, len); - bit = ((dword)1) << (n2_bitlen % 32); - n1 += ((n2_bitlen + 32) / 32) - 1; - n2_bytelen = ((n2_bitlen - 1) / 32) * 4; - n_tmp[n2_bytelen / 4] |= ((dword)1) << ((n2_bitlen - 1) & 0x1f); - - while (n2_bitlen > 0) { - n2_bitlen--; - shl_bignum(n_tmp, 1, len); - if (cmp_bignum(n_tmp, n2, len) != -1) { - sub_bignum(n_tmp, n_tmp, n2, 0, len); - *n1 |= bit; - } - bit >>= 1; - if (bit == 0) { - n1--; - bit = 0x80000000; - } - } - init_bignum(n_tmp, 0, len); -} - -static void inc_bignum(bignum n, dword len) -{ - while ((++*n == 0) && (--len > 0)) n++; -} - -static void init_two_dw(bignum n, dword len) -{ - mov_bignum(glob1, n, len); - glob1_bitlen = bitlen_bignum(glob1, len); - glob1_len_x2 = (glob1_bitlen + 15) / 16; - mov_bignum(glob1_hi, glob1 + len_bignum(glob1, len) - 2, 2); - glob1_hi_bitlen = bitlen_bignum(glob1_hi, 2) - 32; - shr_bignum(glob1_hi, glob1_hi_bitlen, 2); - inv_bignum(glob1_hi_inv, glob1_hi, 2); - shr_bignum(glob1_hi_inv, 1, 2); - glob1_hi_bitlen = (glob1_hi_bitlen + 15) % 16 + 1; - inc_bignum(glob1_hi_inv, 2); - if (bitlen_bignum(glob1_hi_inv, 2) > 32) - { - shr_bignum(glob1_hi_inv, 1, 2); - glob1_hi_bitlen--; - } - glob1_hi_inv_lo = *(word *)glob1_hi_inv; - glob1_hi_inv_hi = *(((word *)glob1_hi_inv) + 1); -} - -static void mul_bignum_word(bignum n1, bignum n2, dword mul, dword len) -{ - dword i, tmp; - - tmp = 0; - for (i = 0; i < len; i++) { - tmp = mul * (*(word *)n2) + *(word *)n1 + tmp; - *(word *)n1 = tmp; - n1 = (dword *)(((word *)n1) + 1); - n2 = (dword *)(((word *)n2) + 1); - tmp >>= 16; - } - *(word *)n1 += tmp; -} - -static void mul_bignum(bignum dest, bignum src1, bignum src2, dword len) -{ - dword i; - - init_bignum(dest, 0, len*2); - for (i = 0; i < len*2; i++) { - mul_bignum_word(dest, src1, *(word *)src2, len*2); - src2 = (dword *)(((word *)src2) + 1); - dest = (dword *)(((word *)dest) + 1); - } -} - -static void not_bignum(bignum n, dword len) -{ - dword i; - for (i = 0; i < len; i++) *(n++) = ~*n; -} - -static void neg_bignum(bignum n, dword len) -{ - not_bignum(n, len); - inc_bignum(n, len); -} - -static dword get_mulword(bignum n) -{ - dword i; - word *wn; - - wn = (word *)n; - i = (((((((((*(wn-1) ^ 0xffff) & 0xffff) * glob1_hi_inv_lo + 0x10000) >> 1) - + (((*(wn-2) ^ 0xffff) * glob1_hi_inv_hi + glob1_hi_inv_hi) >> 1) + 1) - >> 16) + ((((*(wn-1) ^ 0xffff) & 0xffff) * glob1_hi_inv_hi) >> 1) + - (((*wn ^ 0xffff) * glob1_hi_inv_lo) >> 1) + 1) >> 14) + glob1_hi_inv_hi - * (*wn ^ 0xffff) * 2) >> glob1_hi_bitlen; - if (i > 0xffff) i = 0xffff; - return i & 0xffff; -} - -static void dec_bignum(bignum n, dword len) -{ - while ((--*n == 0xffffffff) && (--len > 0)) - n++; -} - -static void calc_a_bignum(bignum n1, bignum n2, bignum n3, dword len) -{ - dword g2_len_x2, len_diff; - word *esi, *edi; - word tmp; - - mul_bignum(glob2, n2, n3, len); - glob2[len*2] = 0; - g2_len_x2 = len_bignum(glob2, len*2+1)*2; - if (g2_len_x2 >= glob1_len_x2) { - inc_bignum(glob2, len*2+1); - neg_bignum(glob2, len*2+1); - len_diff = g2_len_x2 + 1 - glob1_len_x2; - esi = ((word *)glob2) + (1 + g2_len_x2 - glob1_len_x2); - edi = ((word *)glob2) + (g2_len_x2 + 1); - for (; len_diff != 0; len_diff--) { - edi--; - tmp = get_mulword((dword *)edi); - esi--; - if (tmp > 0) { - mul_bignum_word((dword *)esi, glob1, tmp, 2*len); - if ((*edi & 0x8000) == 0) { - if (sub_bignum((dword *)esi, (dword *)esi, glob1, 0, len)) (*edi)--; - } - } - } - neg_bignum(glob2, len); - dec_bignum(glob2, len); - } - mov_bignum(n1, glob2, len); -} - -static void clear_tmp_vars(dword len) -{ - init_bignum(glob1, 0, len); - init_bignum(glob2, 0, len); - init_bignum(glob1_hi_inv, 0, 4); - init_bignum(glob1_hi, 0, 4); - glob1_bitlen = 0; - glob1_hi_bitlen = 0; - glob1_len_x2 = 0; - glob1_hi_inv_lo = 0; - glob1_hi_inv_hi = 0; -} - -static void calc_a_key(bignum n1, bignum n2, bignum n3, bignum n4, dword len) -{ - bignum n_tmp; - dword n3_len, n4_len, n3_bitlen, bit_mask; - - init_bignum(n1, 1, len); - n4_len = len_bignum(n4, len); - init_two_dw(n4, n4_len); - n3_bitlen = bitlen_bignum(n3, n4_len); - n3_len = (n3_bitlen + 31) / 32; - bit_mask = (((dword)1) << ((n3_bitlen - 1) % 32)) >> 1; - n3 += n3_len - 1; - n3_bitlen--; - mov_bignum(n1, n2, n4_len); - while (--n3_bitlen != -1) - { - if (bit_mask == 0) - { - bit_mask = 0x80000000; - n3--; - } - calc_a_bignum(n_tmp, n1, n1, n4_len); - if (*n3 & bit_mask) - calc_a_bignum(n1, n_tmp, n2, n4_len); - else - mov_bignum(n1, n_tmp, n4_len); - bit_mask >>= 1; - } - init_bignum(n_tmp, 0, n4_len); - clear_tmp_vars(len); -} - -static void process_predata(const byte* pre, dword pre_len, byte *buf) -{ - bignum n2, n3; - const dword a = (pubkey.len - 1) / 8; - while (a + 1 <= pre_len) - { - init_bignum(n2, 0, 64); - memmove(n2, pre, a + 1); - calc_a_key(n3, n2, pubkey.key2, pubkey.key1, 64); - - memmove(buf, n3, a); - - pre_len -= a + 1; - pre += a + 1; - buf += a; - } -} - -static void get_blowfish_key(const byte* s, byte* d) -{ - static bool public_key_initialized = false; - if (!public_key_initialized) - { - init_pubkey(); - public_key_initialized = true; - } - byte key[256]; - process_predata(s, len_predata(), key); - memcpy(d, key, 56); -} \ No newline at end of file diff --git a/OpenRa.FileFormats/BlowfishKeyProvider.cs b/OpenRa.FileFormats/BlowfishKeyProvider.cs new file mode 100644 index 0000000000..137104e75a --- /dev/null +++ b/OpenRa.FileFormats/BlowfishKeyProvider.cs @@ -0,0 +1,520 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Linq; + +namespace OpenRa.FileFormats +{ + /* possibly the fugliest C# i've ever seen. */ + + class BlowfishKeyProvider + { + const string pubkeyStr = "AihRvNoIbTn85FZRYNZRcT+i6KpU+maCsEqr3Q5q+LDB5tH7Tz2qQ38V"; + + static sbyte[] char2num = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, + -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; + + class PublicKey + { + public uint[] key1 = new uint[64]; + public uint[] key2 = new uint[64]; + public uint len; + } + PublicKey pubkey = new PublicKey(); + + uint[] glob1 = new uint[64]; + uint glob1_bitlen, glob1_len_x2; + uint[] glob2 = new uint[130]; + uint[] glob1_hi = new uint[4]; + uint[] glob1_hi_inv = new uint[4]; + uint glob1_hi_bitlen; + uint glob1_hi_inv_lo, glob1_hi_inv_hi; + + void init_bignum(uint[] n, uint val, uint len) + { + for (int i = 0; i < len; i++) n[i] = 0; + n[0] = val; + } + + void move_key_to_big(uint[] n, byte[] key, uint klen, uint blen) + { + byte sign; + + if ((key[0] & 0x80) != 0) sign = 0xff; + else sign = 0; + + unsafe + { + fixed (uint* _pn = &n[0]) + { + byte* pn = (byte*)_pn; + uint i = blen * 4; + for (; i > klen; i--) pn[i - 1] = (byte)sign; + for (; i > 0; i--) pn[i - 1] = key[klen - i]; + } + } + } + + void key_to_bignum(uint[] n, byte[] key, uint len) + { + uint keylen; + int i; + + int j = 0; + + if (key[j] != 2) return; + j++; + + if ((key[j] & 0x80) != 0) + { + keylen = 0; + for (i = 0; i < (key[j] & 0x7f); i++) keylen = (keylen << 8) | key[j + i + 1]; + j += (key[j] & 0x7f) + 1; + } + else + { + keylen = key[j]; + j++; + } + if (keylen <= len * 4) + move_key_to_big(n, key.Skip(j).ToArray(), keylen, len); + } + + uint len_bignum(uint[] n, uint len) + { + uint i; + i = len - 1; + while ((i >= 0) && (n[i] == 0)) i--; + return i + 1; + } + + uint bitlen_bignum(uint[] n, uint len) + { + uint ddlen, bitlen, mask; + ddlen = len_bignum(n, len); + if (ddlen == 0) return 0; + bitlen = ddlen * 32; + mask = 0x80000000; + while ((mask & n[ddlen - 1]) == 0) + { + mask >>= 1; + bitlen--; + } + return bitlen; + } + + void init_pubkey() + { + int i = 0; + uint i2, tmp; + byte[] keytmp = new byte[256]; + + init_bignum(pubkey.key2, 0x10001, 64); + + i2 = 0; + while (i < pubkeyStr.Length) + { + tmp = (uint)char2num[pubkeyStr[i++]]; + tmp <<= 6; tmp |= (uint)(byte)char2num[pubkeyStr[i++]]; + tmp <<= 6; tmp |= (uint)(byte)char2num[pubkeyStr[i++]]; + tmp <<= 6; tmp |= (uint)(byte)char2num[pubkeyStr[i++]]; + keytmp[i2++] = (byte)((tmp >> 16) & 0xff); + keytmp[i2++] = (byte)((tmp >> 8) & 0xff); + keytmp[i2++] = (byte)(tmp & 0xff); + } + + key_to_bignum(pubkey.key1, keytmp, 64); + pubkey.len = bitlen_bignum(pubkey.key1, 64) - 1; + } + + uint len_predata() + { + uint a = (pubkey.len - 1) / 8; + return (55 / a + 1) * (a + 1); + } + + int cmp_bignum(uint[] n1, uint[] n2, uint len) + { + + while (len > 0) + { + --len; + if (n1[len] < n2[len]) return -1; + if (n1[len] > n2[len]) return 1; + } + return 0; + } + + void mov_bignum(uint[] dest, uint[] src, uint len) + { + Array.Copy(src, dest, len); + } + + void shr_bignum(uint[] n, int bits, int len) + { + int i; int i2 = bits / 32; + + if (i2 > 0) + { + for (i = 0; i < len - i2; i++) n[i] = n[i + i2]; + for (; i < len; i++) n[i] = 0; + bits = bits % 32; + } + if (bits == 0) return; + for (i = 0; i < len - 1; i++) n[i] = (n[i] >> bits) | (n[i + 1] << (32 - + bits)); + n[i] = n[i] >> bits; + } + + void shl_bignum(uint[] n, int bits, int len) + { + int i, i2; + + i2 = bits / 32; + if (i2 > 0) + { + for (i = len - 1; i > i2; i--) n[i] = n[i - i2]; + for (; i > 0; i--) n[i] = 0; + bits = bits % 32; + } + if (bits == 0) return; + for (i = len - 1; i > 0; i--) n[i] = (n[i] << bits) | (n[i - 1] >> (32 - + bits)); + n[0] <<= bits; + } + + uint sub_bignum(uint[] dest, uint[] src1, uint[] src2, uint carry, int len) + { + uint i1, i2; + + len += len; + unsafe + { + fixed (uint* _ps1 = &src1[0]) + fixed (uint* _ps2 = &src2[0]) + fixed (uint* _pd = &dest[0]) + { + ushort* ps1 = (ushort*)_ps1; + ushort* ps2 = (ushort*)_ps2; + ushort* pd = (ushort*)_pd; + + while (--len != -1) + { + i1 = *ps1++; + i2 = *ps2++; + *pd++ = (ushort)(i1 - i2 - carry); + if (((i1 - i2 - carry) & 0x10000) != 0) carry = 1; else carry = 0; + } + } + } + return carry; + } + + unsafe uint sub_bignum(uint* dest, uint* src1, uint* src2, uint carry, int len) + { + uint i1, i2; + + len += len; + + ushort* ps1 = (ushort*)src1; + ushort* ps2 = (ushort*)src2; + ushort* pd = (ushort*)dest; + + while (--len != -1) + { + i1 = *ps1++; + i2 = *ps2++; + *pd++ = (ushort)(i1 - i2 - carry); + if (((i1 - i2 - carry) & 0x10000) != 0) carry = 1; else carry = 0; + + } + return carry; + } + + void inv_bignum(uint[] n1, uint[] n2, uint len) + { + uint[] n_tmp = new uint[64]; + uint n2_bytelen, bit; + int n2_bitlen; + + int j = 0; + + init_bignum(n_tmp, 0, len); + init_bignum(n1, 0, len); + n2_bitlen = (int)bitlen_bignum(n2, len); + bit = ((uint)1) << (n2_bitlen % 32); + j = ((n2_bitlen + 32) / 32) - 1; + n2_bytelen = (uint)((n2_bitlen - 1) / 32) * 4; + n_tmp[n2_bytelen / 4] |= ((uint)1) << ((n2_bitlen - 1) & 0x1f); + + while (n2_bitlen > 0) + { + n2_bitlen--; + shl_bignum(n_tmp, 1, (int)len); + if (cmp_bignum(n_tmp, n2, len) != -1) + { + sub_bignum(n_tmp, n_tmp, n2, 0, (int)len); + n1[j] |= bit; + } + bit >>= 1; + if (bit == 0) + { + j--; + bit = 0x80000000; + } + } + init_bignum(n_tmp, 0, len); + } + + void inc_bignum(uint[] n, uint len) + { + int i = 0; + while ((++n[i] == 0) && (--len > 0)) i++; + } + + void init_two_dw(uint[] n, uint len) + { + mov_bignum(glob1, n, len); + glob1_bitlen = bitlen_bignum(glob1, len); + glob1_len_x2 = (glob1_bitlen + 15) / 16; + mov_bignum(glob1_hi, glob1.Skip((int)len_bignum(glob1, len) - 2).ToArray(), 2); + glob1_hi_bitlen = bitlen_bignum(glob1_hi, 2) - 32; + shr_bignum(glob1_hi, (int)glob1_hi_bitlen, 2); + inv_bignum(glob1_hi_inv, glob1_hi, 2); + shr_bignum(glob1_hi_inv, 1, 2); + glob1_hi_bitlen = (glob1_hi_bitlen + 15) % 16 + 1; + inc_bignum(glob1_hi_inv, 2); + if (bitlen_bignum(glob1_hi_inv, 2) > 32) + { + shr_bignum(glob1_hi_inv, 1, 2); + glob1_hi_bitlen--; + } + glob1_hi_inv_lo = (ushort)glob1_hi_inv[0]; + glob1_hi_inv_hi = (ushort)(glob1_hi_inv[0] >> 16); + } + + unsafe void mul_bignum_word(ushort *pn1, uint[] n2, uint mul, uint len) + { + uint i, tmp; + unsafe + { + fixed (uint* _pn2 = &n2[0]) + { + ushort* pn2 = (ushort*)_pn2; + + tmp = 0; + for (i = 0; i < len; i++) + { + tmp = mul * (*pn2) + (*pn1) + tmp; + *pn1 = (ushort)tmp; + pn1++; + pn2++; + tmp >>= 16; + } + *pn1 += (ushort)tmp; + } + } + } + + void mul_bignum(uint[] dest, uint[] src1, uint[] src2, uint len) + { + uint i; + + unsafe + { + fixed( uint * _psrc2 = &src2[0] ) + fixed(uint* _pdest = &dest[0]) + { + ushort* psrc2 = (ushort*)_psrc2; + ushort* pdest = (ushort*)_pdest; + + init_bignum(dest, 0, len * 2); + for (i = 0; i < len * 2; i++) + mul_bignum_word(pdest++, src1, *psrc2++, len * 2); + } + } + } + + void not_bignum(uint[] n, uint len) + { + uint i; + for (i = 0; i < len; i++) n[i] = ~n[i]; + } + + void neg_bignum(uint[] n, uint len) + { + not_bignum(n, len); + inc_bignum(n, len); + } + + unsafe uint get_mulword(uint* n) + { + ushort* wn = (ushort*)n; + uint i = (uint)((((((((((*(wn - 1) ^ 0xffff) & 0xffff) * glob1_hi_inv_lo + 0x10000) >> 1) + + (((*(wn - 2) ^ 0xffff) * glob1_hi_inv_hi + glob1_hi_inv_hi) >> 1) + 1) + >> 16) + ((((*(wn - 1) ^ 0xffff) & 0xffff) * glob1_hi_inv_hi) >> 1) + + (((*wn ^ 0xffff) * glob1_hi_inv_lo) >> 1) + 1) >> 14) + glob1_hi_inv_hi + * (*wn ^ 0xffff) * 2) >> (int)glob1_hi_bitlen); + if (i > 0xffff) i = 0xffff; + return i & 0xffff; + } + + void dec_bignum(uint[] n, uint len) + { + int i = 0; + while ((--n[i] == 0xffffffff) && (--len > 0)) + i++; + } + + void calc_a_bignum(uint[] n1, uint[] n2, uint[] n3, uint len) + { + uint g2_len_x2, len_diff; + unsafe + { + fixed( uint* g1 = &glob1[0]) + fixed (uint* g2 = &glob2[0]) + { + mul_bignum(glob2, n2, n3, len); + glob2[len * 2] = 0; + g2_len_x2 = len_bignum(glob2, len * 2 + 1) * 2; + if (g2_len_x2 >= glob1_len_x2) + { + inc_bignum(glob2, len * 2 + 1); + neg_bignum(glob2, len * 2 + 1); + len_diff = g2_len_x2 + 1 - glob1_len_x2; + ushort* esi = ((ushort*)g2) + (1 + g2_len_x2 - glob1_len_x2); + ushort* edi = ((ushort*)g2) + (g2_len_x2 + 1); + for (; len_diff != 0; len_diff--) + { + edi--; + uint tmp = get_mulword((uint*)edi); + esi--; + if (tmp > 0) + { + mul_bignum_word(esi, glob1, tmp, 2 * len); + if ((*edi & 0x8000) == 0) + { + if (0 != sub_bignum((uint*)esi, (uint*)esi, g1, 0, (int)len)) (*edi)--; + } + } + } + neg_bignum(glob2, len); + dec_bignum(glob2, len); + } + mov_bignum(n1, glob2, len); + } + } + } + + void clear_tmp_vars(uint len) + { + init_bignum(glob1, 0, len); + init_bignum(glob2, 0, len); + init_bignum(glob1_hi_inv, 0, 4); + init_bignum(glob1_hi, 0, 4); + glob1_bitlen = 0; + glob1_hi_bitlen = 0; + glob1_len_x2 = 0; + glob1_hi_inv_lo = 0; + glob1_hi_inv_hi = 0; + } + + void calc_a_key(uint[] n1, uint[] n2, uint[] n3, uint[] n4, uint len) + { + uint[] n_tmp = new uint[64]; + uint n3_len, n4_len; + int n3_bitlen; + uint bit_mask; + + unsafe + { + fixed (uint* _pn3 = &n3[0]) + { + uint* pn3 = _pn3; + + init_bignum(n1, 1, len); + n4_len = len_bignum(n4, len); + init_two_dw(n4, n4_len); + n3_bitlen = (int)bitlen_bignum(n3, n4_len); + n3_len = (uint)((n3_bitlen + 31) / 32); + bit_mask = (((uint)1) << ((n3_bitlen - 1) % 32)) >> 1; + pn3 += n3_len - 1; + n3_bitlen--; + mov_bignum(n1, n2, n4_len); + while (--n3_bitlen != -1) + { + if (bit_mask == 0) + { + bit_mask = 0x80000000; + pn3--; + } + calc_a_bignum(n_tmp, n1, n1, n4_len); + if ((*pn3 & bit_mask) != 0) + calc_a_bignum(n1, n_tmp, n2, n4_len); + else + mov_bignum(n1, n_tmp, n4_len); + bit_mask >>= 1; + } + init_bignum(n_tmp, 0, n4_len); + clear_tmp_vars(len); + } + } + } + + unsafe void memcpy(byte* dest, byte* src, int len) + { + while (len-- != 0) *dest++ = *src++; + } + + unsafe void process_predata(byte* pre, uint pre_len, byte *buf) + { + uint[] n2 = new uint[64]; + uint[] n3 = new uint[64]; + + uint a = (pubkey.len - 1) / 8; + while (a + 1 <= pre_len) + { + init_bignum(n2, 0, 64); + fixed( uint * pn2 = &n2[0] ) + memcpy((byte *)pn2, pre, (int)a + 1); + calc_a_key(n3, n2, pubkey.key2, pubkey.key1, 64); + + fixed( uint * pn3 = &n3[0] ) + memcpy(buf, (byte *)pn3, (int)a); + + pre_len -= a + 1; + pre += a + 1; + buf += a; + } + } + + public byte[] DecryptKey(byte[] src) + { + init_pubkey(); + byte[] dest = new byte[256]; + + unsafe + { + fixed (byte* pdest = &dest[0]) + fixed (byte* psrc = &src[0]) + process_predata(psrc, len_predata(), pdest); + } + return dest.Take(56).ToArray(); + } + } +} diff --git a/OpenRa.FileFormats/OpenRa.FileFormats.csproj b/OpenRa.FileFormats/OpenRa.FileFormats.csproj index 7979afdc1a..5e08beb703 100644 --- a/OpenRa.FileFormats/OpenRa.FileFormats.csproj +++ b/OpenRa.FileFormats/OpenRa.FileFormats.csproj @@ -14,7 +14,7 @@ 2.0 - v2.0 + v3.5 true @@ -36,13 +36,16 @@ + + 3.5 + - + @@ -62,10 +65,6 @@ - - {6F5D4280-3D23-41FF-AE2A-511B5553E377} - MixDecrypt - {2F9E7A23-56C0-4286-9C8E-1060A9B2F073} OpenRa.DataStructures diff --git a/OpenRa.FileFormats/Package.cs b/OpenRa.FileFormats/Package.cs index ebefa30998..947e19f3d5 100644 --- a/OpenRa.FileFormats/Package.cs +++ b/OpenRa.FileFormats/Package.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Text; using System.IO; +using System.Linq; namespace OpenRa.FileFormats { @@ -18,11 +19,6 @@ namespace OpenRa.FileFormats readonly long dataStart; readonly Stream s; - //public ICollection Content - //{ - // get { return index.AsReadOnly(); } - //} - public static Dictionary MakeDict(IEnumerable values, Converter keyFunc) { var dict = new Dictionary(); @@ -63,7 +59,7 @@ namespace OpenRa.FileFormats { BinaryReader reader = new BinaryReader(s); byte[] keyblock = reader.ReadBytes(80); - byte[] blowfishKey = MixDecrypt.MixDecrypt.BlowfishKey(keyblock); + byte[] blowfishKey = new BlowfishKeyProvider().DecryptKey(keyblock); uint[] h = ReadUints(reader, 2); diff --git a/OpenRa.Game/Actor.cs b/OpenRa.Game/Actor.cs index c1479e0dd0..1c1a673329 100644 --- a/OpenRa.Game/Actor.cs +++ b/OpenRa.Game/Actor.cs @@ -6,6 +6,7 @@ using OpenRa.FileFormats; using System.Windows.Forms; using OpenRa.Game.Graphics; +using IjwFramework.Types; namespace OpenRa.Game { @@ -13,9 +14,8 @@ namespace OpenRa.Game { public readonly Game game; - public abstract float2 RenderLocation { get; } public Player owner; - public abstract Sprite[] CurrentImages { get; } + public abstract IEnumerable> CurrentImages { get; } public virtual void Tick(Game game, int t) { } protected Actor(Game game) diff --git a/OpenRa.Game/Game.cs b/OpenRa.Game/Game.cs index 70c40a5611..c81428fa8f 100644 --- a/OpenRa.Game/Game.cs +++ b/OpenRa.Game/Game.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using OpenRa.FileFormats; +using System.Linq; using OpenRa.Game.Graphics; @@ -23,7 +24,7 @@ namespace OpenRa.Game public readonly Dictionary players = new Dictionary(); // temporary, until we remove all the subclasses of Building - public Dictionary> buildingCreation = new Dictionary>(); + public Dictionary> buildingCreation; public Player LocalPlayer { get { return players[localPlayerIndex]; } } @@ -48,15 +49,13 @@ namespace OpenRa.Game network = new Network(); - buildingCreation.Add("proc", (location, owner) => new Refinery(location, owner, this)); - buildingCreation.Add("weap", (location, owner) => new WarFactory(location, owner, this)); + var buildings = new[] { "fact", "powr", "apwr", "barr", "atek", "stek", "dome" }; + buildingCreation = buildings.ToDictionary(s => s, + s => (Func)( + (l, o) => new Building(s, l, o, this))); - string[] buildings = { "fact", "powr", "apwr", "barr", "atek", "stek", "dome" }; - foreach (string s in buildings) - { - var t = s; - buildingCreation.Add(t, (location, owner) => new Building(t, location, owner, this)); - } + buildingCreation.Add("proc", (location, owner) => new Refinery(location, owner, this)); + buildingCreation.Add("weap", (location, owner) => new WarFactory(location, owner, this)); controller = new Controller(this); // CAREFUL THERES AN UGLY HIDDEN DEPENDENCY HERE STILL worldRenderer = new WorldRenderer(renderer, world); diff --git a/OpenRa.Game/Graphics/Animation.cs b/OpenRa.Game/Graphics/Animation.cs index d1debfef51..b3be057d05 100644 --- a/OpenRa.Game/Graphics/Animation.cs +++ b/OpenRa.Game/Graphics/Animation.cs @@ -15,7 +15,7 @@ namespace OpenRa.Game.Graphics Play( "idle" ); } - public Sprite[] Images { get { return new Sprite[] { currentSequence.GetSprite( frame ) }; } } + public Sprite Image { get { return currentSequence.GetSprite( frame ); } } public float2 Center { get { return 0.25f * new float2(currentSequence.GetSprite(0).bounds.Size); } } public void Play( string sequenceName ) diff --git a/OpenRa.Game/Graphics/Region.cs b/OpenRa.Game/Graphics/Region.cs index 093ab919fc..0f66d54723 100644 --- a/OpenRa.Game/Graphics/Region.cs +++ b/OpenRa.Game/Graphics/Region.cs @@ -44,7 +44,7 @@ namespace OpenRa.Game.Graphics { Button = mi.Button, Event = mi.Event, - Location = mi.Location - Location + Location = mi.Location - location }); return mouseHandler != null; } diff --git a/OpenRa.Game/Graphics/WorldRenderer.cs b/OpenRa.Game/Graphics/WorldRenderer.cs index 8c46ad7fda..8c610790bd 100644 --- a/OpenRa.Game/Graphics/WorldRenderer.cs +++ b/OpenRa.Game/Graphics/WorldRenderer.cs @@ -31,17 +31,19 @@ namespace OpenRa.Game.Graphics foreach (Actor a in world.Actors) { - Sprite[] images = a.CurrentImages; - float2 loc = a.RenderLocation; + var images = a.CurrentImages; - if (loc.X > rect.Right || loc.X < rect.Left - images[0].bounds.Width) - continue; + foreach( var image in images ) + { + var loc = image.Second; - if (loc.Y > rect.Bottom || loc.Y < rect.Top - images[0].bounds.Height) - continue; + if( loc.X > rect.Right || loc.X < rect.Left - image.First.bounds.Width ) + continue; + if( loc.Y > rect.Bottom || loc.Y < rect.Top - image.First.bounds.Height ) + continue; - foreach (Sprite image in images) - spriteRenderer.DrawSprite(image, loc, (a.owner != null) ? a.owner.Palette : 0); + spriteRenderer.DrawSprite( image.First, loc, ( a.owner != null ) ? a.owner.Palette : 0 ); + } } spriteRenderer.Flush(); diff --git a/OpenRa.Game/MainWindow.cs b/OpenRa.Game/MainWindow.cs index 37c869ecdd..fca1371b5b 100644 --- a/OpenRa.Game/MainWindow.cs +++ b/OpenRa.Game/MainWindow.cs @@ -40,15 +40,18 @@ namespace OpenRa.Game renderer = new Renderer(this, GetResolution(settings), windowed); SheetBuilder.Initialize( renderer ); - game = new Game( settings.GetValue( "map", "scm12ea.ini" ), renderer, new int2( ClientSize ) ); + game = new Game( settings.GetValue( "map", "scg11eb.ini" ), renderer, new int2( ClientSize ) ); SequenceProvider.ForcePrecache(); + Unit controlled; + game.world.Add( new Unit( "mcv", new int2( 5, 5 ), game.players[ 3 ], game ) ); game.world.Add( new Unit( "mcv", new int2( 7, 5 ), game.players[ 2 ], game ) ); - Unit mcv = new Unit( "mcv", new int2( 9, 5 ), game.players[ 1 ], game ); - game.controller.orderGenerator = mcv; - game.world.Add( mcv ); + + game.world.Add(controlled = new Unit("mcv", new int2(9, 5), game.players[1], game)); + + game.controller.orderGenerator = controlled; sidebar = new Sidebar(Race.Soviet, renderer, game); @@ -83,7 +86,7 @@ namespace OpenRa.Game { base.OnMouseMove(e); - if (e.Button == MouseButtons.Right) + if (e.Button == MouseButtons.Middle) { int2 p = new int2(e.Location); game.viewport.Scroll(lastPos - p); diff --git a/OpenRa.Game/PlayerOwned.cs b/OpenRa.Game/PlayerOwned.cs index 06e969abaf..8c65b3866f 100644 --- a/OpenRa.Game/PlayerOwned.cs +++ b/OpenRa.Game/PlayerOwned.cs @@ -1,4 +1,6 @@ +using System.Collections.Generic; using OpenRa.Game.Graphics; +using IjwFramework.Types; namespace OpenRa.Game { @@ -17,11 +19,7 @@ namespace OpenRa.Game this.location = location; } - public override float2 RenderLocation - { - get { return 24.0f * (float2)location; } - } - - public override Sprite[] CurrentImages { get { return animation.Images; } } + public override IEnumerable> CurrentImages { get { yield return Pair.New( animation.Image, 24 * (float2)location ); } } } } + \ No newline at end of file diff --git a/OpenRa.Game/Refinery.cs b/OpenRa.Game/Refinery.cs index b71d304f1b..c21facc991 100644 --- a/OpenRa.Game/Refinery.cs +++ b/OpenRa.Game/Refinery.cs @@ -1,5 +1,7 @@ using OpenRa.Game.Graphics; using System.Linq; +using System.Collections.Generic; +using IjwFramework.Types; namespace OpenRa.Game { @@ -39,13 +41,14 @@ namespace OpenRa.Game }); } - public override Sprite[] CurrentImages + public override IEnumerable> CurrentImages { get { return (roof == null) ? base.CurrentImages - : (base.CurrentImages.Concat( roof.Images ).ToArray()); + : (base.CurrentImages.Concat( + new[] { Pair.New(roof.Image, 24 * (float2)location) })); } } diff --git a/OpenRa.Game/Sidebar.cs b/OpenRa.Game/Sidebar.cs index 24f27f77ce..4974a67753 100644 --- a/OpenRa.Game/Sidebar.cs +++ b/OpenRa.Game/Sidebar.cs @@ -126,7 +126,7 @@ namespace OpenRa.Game { if (kvp.Value != null) { - clockRenderer.DrawSprite(clockAnimations[kvp.Key].Images[0], region.Location.ToFloat2() + kvp.Value.location, 0); + clockRenderer.DrawSprite(clockAnimations[kvp.Key].Image, region.Location.ToFloat2() + kvp.Value.location, 0); clockAnimations[kvp.Key].Tick(1); } } diff --git a/OpenRa.Game/Tree.cs b/OpenRa.Game/Tree.cs index 14b82f361d..e295eea0e5 100644 --- a/OpenRa.Game/Tree.cs +++ b/OpenRa.Game/Tree.cs @@ -4,6 +4,7 @@ using System.Text; using OpenRa.FileFormats; using System.Drawing; using OpenRa.Game.Graphics; +using IjwFramework.Types; namespace OpenRa.Game { @@ -19,8 +20,13 @@ namespace OpenRa.Game } Sprite[] currentImages; - public override Sprite[] CurrentImages { get { return currentImages; } } - - public override float2 RenderLocation { get { return 24 * location; } } + public override IEnumerable> CurrentImages + { + get + { + foreach( var x in currentImages ) + yield return Pair.New( x, 24 * (float2)location ); + } + } } } diff --git a/OpenRa.Game/Unit.cs b/OpenRa.Game/Unit.cs index 4b9bd67528..994429d0ec 100644 --- a/OpenRa.Game/Unit.cs +++ b/OpenRa.Game/Unit.cs @@ -1,5 +1,9 @@ using System; +using System.Collections.Generic; +using System.Linq; + using OpenRa.Game.Graphics; +using IjwFramework.Types; namespace OpenRa.Game { @@ -67,14 +71,20 @@ namespace OpenRa.Game currentOrder( t ); } - public override float2 RenderLocation + public override IEnumerable> CurrentImages + { + get + { + yield return Centered( animation.Image, CenterLocation ); + } + } + + public float2 CenterLocation { get { float fraction = ( moveFraction > 0 ) ? (float)moveFraction / moveFractionTotal : 0f; - - float2 location = 24 * float2.Lerp( fromCell, toCell, fraction ); - return ( location - renderOffset ).Round(); + return new float2( 12, 12 ) + 24 * float2.Lerp( fromCell, toCell, fraction ); } } @@ -97,5 +107,34 @@ namespace OpenRa.Game } public void PrepareOverlay(Game game, int2 xy) { } + + protected static Pair Centered( Sprite s, float2 location ) + { + var loc = location - 0.5f * s.size; + return Pair.New( s, loc.Round() ); + } + } + + class TurretedUnit : Unit + { + Animation turretAnim; + int turretFacing { get { return facing; } } + + public TurretedUnit( string name, int2 cell, Player owner, Game game ) + : base( name, cell, owner, game ) + { + turretAnim = new Animation( name ); + turretAnim.PlayFetchIndex( "turret", () => turretFacing ); + } + + public override IEnumerable> CurrentImages + { + get + { + foreach( var x in base.CurrentImages ) + yield return x; + yield return Centered( turretAnim.Image, CenterLocation ); + } + } } } diff --git a/OpenRa.sln b/OpenRa.sln index 721be94a1d..1ef2b24136 100644 --- a/OpenRa.sln +++ b/OpenRa.sln @@ -1,12 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 10.00 # Visual Studio 2008 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MixDecrypt", "MixDecrypt\MixDecrypt.vcproj", "{6F5D4280-3D23-41FF-AE2A-511B5553E377}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenRa.FileFormats", "OpenRa.FileFormats\OpenRa.FileFormats.csproj", "{BDAEAB25-991E-46A7-AF1E-4F0E03358DAA}" - ProjectSection(ProjectDependencies) = postProject - {6F5D4280-3D23-41FF-AE2A-511B5553E377} = {6F5D4280-3D23-41FF-AE2A-511B5553E377} - EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenRa.Game", "OpenRa.Game\OpenRa.Game.csproj", "{0DFB103F-2962-400F-8C6D-E2C28CCBA633}" EndProject @@ -20,10 +15,6 @@ Global Release (x86)|Win32 = Release (x86)|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {6F5D4280-3D23-41FF-AE2A-511B5553E377}.Debug (x86)|Win32.ActiveCfg = Release|Win32 - {6F5D4280-3D23-41FF-AE2A-511B5553E377}.Debug (x86)|Win32.Build.0 = Release|Win32 - {6F5D4280-3D23-41FF-AE2A-511B5553E377}.Release (x86)|Win32.ActiveCfg = Release|Win32 - {6F5D4280-3D23-41FF-AE2A-511B5553E377}.Release (x86)|Win32.Build.0 = Release|Win32 {BDAEAB25-991E-46A7-AF1E-4F0E03358DAA}.Debug (x86)|Win32.ActiveCfg = Debug|x86 {BDAEAB25-991E-46A7-AF1E-4F0E03358DAA}.Debug (x86)|Win32.Build.0 = Debug|x86 {BDAEAB25-991E-46A7-AF1E-4F0E03358DAA}.Release (x86)|Win32.ActiveCfg = Release|x86 diff --git a/sequences.xml b/sequences.xml index c57eaa2504..4068d697f3 100644 --- a/sequences.xml +++ b/sequences.xml @@ -134,6 +134,20 @@ + + + + + + + + + + + + + +