
TLOU2 DC स्क्रिप्ट्स के लिए एक डिस्सेम्बलर और प्रायोगिक डीकंपाइलर।

dconstruct The Last of Us Part II में उपयोग किए जाने वाले DC-Script फ़ाइलों के लिए एक रिवर्स इंजीनियरिंग उपकरण है। इसमें एक डिसअसेंबलर और एक डीकंपाइलर शामिल है।
यह .asm फ़ाइलें आउटपुट करता है जिनमें डिसअसेंबल संरचनाएँ और बाइटकोड होते हैं, साथ ही .dcpl (DC स्यूडो भाषा) फ़ाइलें जिनमें C-जैसा स्यूडो कोड होता है।
आप कमांड लाइन के माध्यम से फ़ाइलों में संपादन भी कर सकते हैं, जिसमें बिना अधिक प्रयास के पूरी संरचनाओं को बदलना शामिल है। इससे .bin फ़ाइलों के अंदर कुछ मान बदलने वाले मॉड बनाना बेहद आसान हो जाता है।
-e फ़्लैग के माध्यम से संपादन करना, नई फ़ाइलें बनाना जिनका उपयोग आप मॉड के लिए कर सकते हैंपहले, यह अनुशंसित है कि आप अनज़िप किए गए dconstruct निर्देशिका को किसी सुरक्षित स्थान पर ले जाएँ, जैसे C:\Program Files।
dconstruct का उपयोग यथासंभव आसान बनाने के लिए, यह अनुशंसित है कि आप dconstruct फ़ोल्डर के अंदर .\bin निर्देशिका को अपने PATH में जोड़ें। आप इसके बारे में यहाँ अधिक जान सकते हैं, या इन त्वरित चरणों का पालन कर सकते हैं:

सुनिश्चित करें कि आपका पथ "\bin" पर समाप्त होता है न कि "\dconstruct" पर।
सभी खुले संवादों पर 'OK' क्लिक करें।
यह सत्यापित करने के लिए कि यह काम कर गया, एक नया कमांड प्रॉम्प्ट खोलें और dconstruct --about टाइप करें। आपको प्रोग्राम से कुछ आउटपुट देखना चाहिए और कोई त्रुटि संदेश नहीं देखना चाहिए।
अपनी पहली डिसअसेंबल फ़ाइल उत्पन्न करने के लिए कमांड लाइन में इस तरह एक कमांड चलाएँ:```shell dconstruct my_bin_file.bin
यह आपके इनपुट फ़ाइल के समान निर्देशिका में `my_bin_file.bin.asm` नामक एक फ़ाइल आउटपुट करेगा। फिर आप उस फ़ाइल को टेक्स्ट/कोड एडिटर का उपयोग करके खोल सकते हैं। मैं VSCode जैसे किसी एडिटर की सलाह दूंगा जो उन्नत खोज सुविधाएँ प्रदान करता है और बड़ी फ़ाइलों को संभालने में अच्छा है। मानक Windows नोटपैड की अनुशंसा नहीं की जाती है।
किसी फ़ाइल को डीकंपाइल करने के लिए, कमांड चलाते समय `--decompile` फ़्लैग जोड़ें।
# कमांड लाइन आर्गुमेंट्स
- `-i` - इनपुट फ़ाइल या फ़ोल्डर। यदि इनपुट पथ को पहले आर्गुमेंट के रूप में पास किया जा रहा है तो इसे छोड़ा जा सकता है।
- `-o` - आउटपुट पथ। यदि आपका इनपुट पथ एक फ़ोल्डर है, तो यह कोई फ़ाइल नहीं हो सकता। यदि कोई आउटपुट निर्दिष्ट नहीं है, तो .txt फ़ाइल इनपुट फ़ाइल के बगल में रखी जाएगी। यदि इनपुट एक फ़ोल्डर है और कोई आउटपुट निर्दिष्ट नहीं है, तो प्रोग्राम वर्तमान कार्यशील निर्देशिका में एक "output" निर्देशिका बनाएगा और सभी फ़ाइलों को वहाँ रखेगा।
- सिडबेस को एक्सीक्यूटेबल के बगल में स्थित `sidbase.bin` से लोड किया जाता है।
- `--no_decompile` - .dcpl फ़ाइल में डीकंपाइल्ड स्यूडो कोड को उत्सर्जित न करें। फ़ाइल .asm फ़ाइल के बगल में रखी जाएगी। डिफ़ॉल्ट रूप से यह false है।
- `--no_optimize` - dcpl कोड को ऑप्टिमाइज़ और साफ़ न करें। इसमें फ़ंक्शन कॉल को इनलाइन करना, अप्रयुक्त चर हटाना, संगत for लूप को foreach लूप में बदलना, और कुछ if-else श्रृंखलाओं को match एक्सप्रेशन में बदलना शामिल है।
- `--pascal_case` - dcpl आउटपुट में गेम के फ़ंक्शन नामों को पास्कल केस में बदलें, उदा. get-boolean -> GetBoolean।
- `--graphs` - सभी डीकंपाइल किए गए फ़ंक्शनों के लिए कंट्रोल फ्लो ग्राफ़ वाली .svg फ़ाइलें उत्सर्जित करें। प्रत्येक .bin फ़ाइल के लिए उसके सभी ग्राफ़ वाला अपना फ़ोल्डर बनता है। यह डीकंपाइलेशन की गति को **काफी** धीमा कर देता है, इसलिए एक साथ बड़ी संख्या में फ़ाइलों को डीकंपाइल करते समय इसकी अनुशंसा नहीं की जाती है।
- `--emit_once` - एक ही संरचना को डिसअसेंबली में दो बार उत्सर्जित होने से रोकता है। यदि कोई संरचना कई बार दिखाई देती है, तो केवल पहली बार ही पूरी तरह उत्सर्जित की जाएगी, और अन्य सभी अवसरों को `ALREADY_EMITTED` टैग से बदल दिया जाएगा। इससे फ़ाइल का आकार काफी कम हो सकता है।
- `-e` - एक संपादन करें। नीचे दिए गए अनुभाग में अधिक जानकारी।
- `--edit_file` - एक संपादन फ़ाइल प्रदान करें। एक संपादन फ़ाइल में प्रति पंक्ति एक संपादन होता है। यह `-e` फ़्लैग के समान सिंटैक्स का उपयोग करता है।
# डिस्सेम्बलर क्या है?
एक [डिस्सेम्बलर](https://en.wikipedia.org/wiki/Disassembler) एक उपकरण है जो बाइनरी निर्देशों (उर्फ [बाइटकोड](https://en.wikipedia.org/wiki/Bytecode) या [मशीन कोड](https://en.wikipedia.org/wiki/Machine_code)) को पढ़ता है और प्रत्येक को एक मानव-पठनीय संस्करण में अनुवादित करता है जिसे [मनेमोनिक](https://en.wikipedia.org/wiki/Assembly_language#Mnemonics) कहा जाता है। डिस्सेम्बलर आमतौर पर इन निर्देशों के अर्थ के बारे में अधिक व्याख्या करने का प्रयास नहीं करते हैं और केवल उन्हें 1-1 रूप में उनके पठनीय संस्करणों में बदल देते हैं। उदाहरण के लिए, निर्देश:```arm
15 00 00 00
4A 01 01 00
43 31 01 00
1C 00 00 01
निम्नलिखित मानव-पठनीय संस्करणों में डिस्सेम्बल किए जाते हैं:```arm LookupPointer r0, 0 LoadStaticU64Imm r1, 1 Move r49, r1 CallFf r0, r0, 1
बाइटकोड में सभी संख्याएँ [हेक्साडेसिमल](https://en.wikipedia.org/wiki/hexadecimal) में लिखी जाती हैं। प्रत्येक पंक्ति में पहला कॉलम `opcode` या निष्पादित किए जाने वाले निर्देश के प्रकार को दर्शाता है। अगला कॉलम गंतव्य रजिस्टर है, जहाँ संक्रिया का परिणाम संग्रहीत किया जाएगा। अंतिम दो कॉलम प्रचालक 1 और 2 हैं, जो या तो रजिस्टर हैं या शाब्दिक संख्याएँ हैं जिन पर संक्रिया की जाएगी। सभी निर्देश सभी 4 बाइट्स का उपयोग नहीं करते, उदाहरण के लिए, पहले `LookupPointer` निर्देश को केवल एक प्रचालक की आवश्यकता होती है।
dconstruct डिसअसेंबलर कुछ अतिरिक्त जानकारी भी जोड़ता है जिसका उद्देश्य निर्देशों को पढ़ना थोड़ा आसान बनाना है। यह कोड में शाखाओं को ट्रेस करना आसान बनाने के लिए लेबल (जैसे `L_0`) भी सम्मिलित करता है।```arm
15 00 00 00 LookupPointer r0, 0 r0 = ST[0] -> <is-player-abby?>
4A 01 01 00 LoadStaticU64Imm r1, 1 r1 = ST[1] -> <player>
43 31 01 00 Move r49, r1 r49 = player
1C 00 00 01 CallFf r0, r0, 1 r0 = is-player-abby?(player)
2F 0D 00 00 BranchIfNot r0, 0xD IF NOT r0 => L_0
यह तब उपयोगी है जब आप प्रोग्राम द्वारा बहुत अधिक अनुमान लगाए बिना फ़ाइल की कच्ची सामग्री देखना चाहते हैं। लेकिन कोड के बड़े ब्लॉकों के लिए इसे पढ़ना मुश्किल हो सकता है, क्योंकि कोई संरचना नहीं होती है। यह वह जगह है जहाँ एक डीकंपाइलर काम आता है।
डीकंपाइलर एक कंपाइलर का विपरीत है। एक कंपाइलर एक प्रोग्राम है जो मानव-लिखित कोड (जैसे C, Java, C++, ...) लेता है और मशीन निर्देश उत्पन्न करता है। TLOU2 और कई अन्य ND गेम्स के मामले में, उपयोग की जाने वाली स्क्रिप्टिंग भाषा को 'DC' कहा जाता है, जो मूल रूप से प्रोग्रामिंग भाषा Racket>) का एक संस्करण है, और "मशीन" सिर्फ गेम ही है जो गेम चलने के दौरान निर्देशों को निष्पादित करता है। संक्षेप में, प्रोग्रामर DC लिखते हैं और उस कोड को .bin फ़ाइलों में बदलने के लिए एक कंपाइलर का उपयोग करते हैं जो गेम के साथ शिप की जाती हैं।
एक डीकंपाइलर ऊपर से डिस्सेम्बल किए गए कोड को लेता है और जिसे स्यूडो कोड के रूप में जाना जाता है, उसे उत्पन्न करता है। स्यूडो कोड मूल स्रोत कोड के पुनर्निर्माण का एक प्रयास है जिसका उपयोग कच्चे निर्देशों को उत्पन्न करने के लिए किया गया था। इसका उद्देश्य कोड को समझना काफी आसान बनाना है, हालांकि, स्यूडो कोड उत्पन्न करने की प्रक्रिया काफी जटिल है क्योंकि स्रोत कोड के कई अलग-अलग संस्करण हैं जो अंतिम बाइट कोड उत्पन्न कर सकते हैं, साथ ही संकलन के दौरान होने वाले अनुकूलन भी।
वर्तमान में, dconstruct डीकंपाइलर का आउटपुट मूल DC के समान वाक्यात्मक रूप से नहीं है। DC (अर्थात Racket) एक कार्यात्मक प्रोग्रामिंग भाषा है जिसमें एक अनूठी वाक्यविन्यास है जो उन प्रोग्रामरों के लिए f*cking अपठनीय है जो इसके आदी नहीं हैं। इस कारण से, मैंने अभी के लिए स्यूडो कोड को C जैसा दिखने का चयन किया है जो अधिकांश लोगों के लिए पढ़ने में आसान होना चाहिए। हालांकि, Racket के साथ-साथ Python संस्करण सहित अधिक सिंटैक्स बनाने की योजना है।
43 00 31 00 15 01 00 00 43 02 00 00 43 31 02 00 1B 01 01 01 43 02 00 00 40 03 01 00 24 02 02 03 2F 0B 02 00 40 02 02 00 2D 0C 00 00 40 02 03 00 43 03 02 00 15 04 04 00 43 05 01 00 43 31 05 00 1C 04 04 01 07 03 03 04 43 01 03 00 00 01 01 00
इससे, यह बताना लगभग असंभव है कि कोड क्या कर रहा है।
## Disassembled code with labels & symbol table```arm
sqrt-sign = script-lambda [0x9A8D8] {
[1 args]
0000 0x09A928 43 00 31 00 Move r0, r49 r0 = arg_0
0001 0x09A930 15 01 00 00 LookupPointer r1, 0 r1 = ST[0] -> <absf>
0002 0x09A938 43 02 00 00 Move r2, r0 r2 = arg_0
0003 0x09A940 43 31 02 00 Move r49, r2 r49 = arg_0
0004 0x09A948 1B 01 01 01 Call r1, r1, 1 r1 = absf(arg_0)
0005 0x09A950 43 02 00 00 Move r2, r0 r2 = arg_0
0006 0x09A958 40 03 01 00 LoadStaticFloatImm r3, 1 r3 = ST[1] -> <0.000000>
0007 0x09A960 24 02 02 03 FGreaterThanEqual r2, r2, r3 r2 = r2 >= r3
0008 0x09A968 2F 0B 02 00 BranchIfNot r2, 0xB IF NOT r2 => L_0
0009 0x09A970 40 02 02 00 LoadStaticFloatImm r2, 2 r2 = ST[2] -> <1.000000>
000A 0x09A978 2D 0C 00 00 Branch 0xC GOTO => L_1
L_0:
000B 0x09A980 40 02 03 00 LoadStaticFloatImm r2, 3 r2 = ST[3] -> <-1.000000>
L_1:
000C 0x09A988 43 03 02 00 Move r3, r2 r3 = -1.000000
000D 0x09A990 15 04 04 00 LookupPointer r4, 4 r4 = ST[4] -> <sqrt>
000E 0x09A998 43 05 01 00 Move r5, r1 r5 = RET_absf
000F 0x09A9A0 43 31 05 00 Move r49, r5 r49 = RET_absf
0010 0x09A9A8 1C 04 04 01 CallFf r4, r4, 1 r4 = sqrt(RET_absf)
0011 0x09A9B0 07 03 03 04 FMul r3, r3, r4 -1.000000 = -1.000000 * RET_sqrt
0012 0x09A9B8 43 01 03 00 Move r1, r3 r1 = -1.000000
0013 0x09A9C0 00 01 01 00 Return r1 Return
SYMBOL TABLE:
0000 0x09A9C8 function: absf
0001 0x09A9D0 float: 0.000000
0002 0x09A9D8 float: 1.000000
0003 0x09A9E0 float: -1.000000
0004 0x09A9E8 function: sqrt
}
कोड अब काफी अधिक पढ़ने योग्य है, लेकिन यदि आप असेंबली पढ़ने के आदी नहीं हैं तो भी एकल शाखा पढ़ने में कष्टप्रद है।
यहाँ बहुत अधिक विस्तार में जाए बिना, एक नियंत्रण प्रवाह ग्राफ (CFG) असेंबली कोड को विभिन्न शाखा निर्देशों के साथ "नोड्स" में विभाजित करता है। यह महत्वपूर्ण है जब हम कोड का विश्लेषण करते हैं ताकि यह पता लगाया जा सके कि प्रोग्राम का "प्रवाह" विभिन्न पथों में कहाँ विचलित हो सकता है, जिसके लिए हमें चर, if statements, for-loops, आदि उत्पन्न करने की आवश्यकता हो सकती है। इन ग्राफों को पृष्ठभूमि में उत्पन्न करने की आवश्यकता होती है, लेकिन आप उन्हें --graphs प्रोग्राम फ्लैग का उपयोग करके छवियों में प्रिंट कर सकते हैं।
u64? sqrt-sign(f32 arg_0) { f32 var_1; if (arg_0 >= 0.00) { var_1 = 1.00; } else { var_1 = -1.00; } return var_1 * sqrt(absf(arg_0)); }
फ़ंक्शन का उद्देश्य अब बहुत स्पष्ट है, हम तर्क का निरपेक्ष मान लेते हैं, उस मान का वर्गमूल लेते हैं और फिर इसे तर्क के मूल चिह्न से गुणा करते हैं। उदाहरण के लिए, `sqrt-sign(-9) = -3`.
## अनुकूलन पास
dconstruct स्वचालित रूप से छद्म कोड पर अनुकूलन पास लागू करता है। यहाँ कुछ उदाहरण दिए गए हैं:
### फ़ंक्शन कॉल इनलाइनिंग
#### पहले```c
u64? set-arrow-explosive-handle-rootvars() {
u64? var_0 = get-uint64(fx-handle, self);
u64? var_1 = get-float(kill, self);
set-effect-float(var_0, killradius, var_1);
u64? var_2 = get-uint64(fx-handle, self);
u64? var_3 = get-float(strong, self);
set-effect-float(var_2, strongradius, var_3);
u64? var_4 = get-uint64(fx-handle, self);
u64? var_5 = get-float(weak, self);
u64? var_6 = set-effect-float(var_4, weakradius, var_5);
return var_6;
}
u64? set-arrow-explosive-handle-rootvars() { set-effect-float(get-uint64(fx-handle, self), killradius, get-float(kill, self)); set-effect-float(get-uint64(fx-handle, self), strongradius, get-float(strong, self)); return set-effect-float(get-uint64(fx-handle, self), weakradius, get-float(weak, self)); }
### Foreach लूप्स
### पहले```c#
u64? bmm-deactivate-all(u64? arg_0) {
u64? var_0 = darray-count(arg_0);
begin-foreach();
for (u64 i = 0; i < var_0; i++) {
u64? var_1 = darray-at(arg_0, i);
u16 var_2;
if (var_1 && *(u16*)(var_1 + 12) == 7) {
var_2 = *(u64*)var_1;
} else if (var_1 && *(u16*)(var_1 + 12) == 5) {
var_2 = *(u64*)var_1;
} else if (var_1 && *(u16*)(var_1 + 12) == 4) {
var_2 = *(u64*)var_1;
} else {
var_2 = 0;
}
net-send-event-all(deactivate, var_2);
}
u64? var_3 = end-foreach();
return var_3;
}
u64? bmm-deactivate-all(u64? arg_0) { foreach (u64? var_1 : arg_0) { u16 var_2; if (var_1 && (u16)(var_1 + 12) == 7) { var_2 = (u64)var_1; } else if (var_1 && (u16)(var_1 + 12) == 5) { var_2 = (u64)var_1; } else if (var_1 && (u16)(var_1 + 12) == 4) { var_2 = (u64)var_1; } else { var_2 = 0; } net-send-event-all(deactivate, var_2); } }
### मिलान अभिव्यक्तियाँ
### पहले```scala
string #C57EE0A64537AE8F(u16 arg_0) {
string var_0;
if (arg_0 == 0) {
var_0 = "Militia";
} else if (arg_0 == 1) {
var_0 = "Scars";
} else if (arg_0 == 2) {
var_0 = "Rattlers";
} else if (arg_0 == 3) {
var_0 = "Infected";
} else if (arg_0 == 4) {
var_0 = "Max Num Factions";
} else {
var_0 = "Invalid";
}
return var_0;
}
string #C57EE0A64537AE8F(u16 arg_0) { return match (arg_0) { 0 -> "Militia" 1 -> "Scars" 2 -> "Rattlers" 3 -> "Infected" 4 -> "Max Num Factions" else -> "Invalid" }; }
## एक डिसैसेंबल की गई संरचना का उदाहरण```c
*ellie-weapons* = symbol-array [0x00190] {
[0] int: 6
[1] int: 0
[2] array [0x198] {size: 6} {
[0] anonymous struct [0x780] {
[0] sid: pistol-beretta
}
[1] anonymous struct [0x788] {
[0] sid: pistol-revolver-taurus
}
[2] anonymous struct [0x790] {
[0] sid: rifle-remington-bolt
}
[3] anonymous struct [0x798] {
[0] sid: bow-ellie
}
[4] anonymous struct [0x7a0] {
[0] sid: shotgun-remington-pump
}
[5] anonymous struct [0x7a8] {
[0] sid: rifle-mpx5
}
}
}
DC फ़ाइलों को -e फ़्लैग का उपयोग करके संपादित करना
आप DC फ़ाइलों में संपादन लागू करने के लिए -e फ़्लैग का उपयोग कर सकते हैं। ये संपादन मूल फ़ाइल की एक नई प्रतिलिपि में सहेजे जाते हैं, जिससे मूल फ़ाइल अछूती रहती है। एक साथ कई संपादन करने के लिए एक साथ कई -e फ़्लैग निर्दिष्ट किए जा सकते हैं।
वैकल्पिक रूप से, आप प्रोग्राम को एक संपादन फ़ाइल का पथ प्रदान कर सकते हैं। एक संपादन फ़ाइल में प्रति पंक्ति एक संपादन होता है। यह -e फ़्लैग के समान सिंटैक्स का उपयोग करता है, लेकिन यदि आप एक साथ कई संपादन लागू करना चाहते हैं तो इसका उपयोग करना थोड़ा आसान होना चाहिए।
संपादन डिसअसेंबली और डीकंपिलेशन से पहले होता है, इसलिए संपादन उत्पन्न फ़ाइलों में दिखाई देगा।
प्रत्येक संपादन इस सिंटैक्स का अनुसरण करता है:```xml
मान लीजिए आपके पास इस प्रकार की एक संरचना है:```c++ [4] firearm-gameplay-def [0x11C28] { [0] float 0.7 // might represent the rate of fire, so i want to lower it for my mod ... }
To replace the first member variable (index 0) with the float value 0.5, the edit command would be:
`-e 0x11C28[0]=0.5`
The structure we want to edit is at `0x11C28`, and we want the first member variable (the 0 to the left of the float). We then put the new value after the `=`, 0.5 in this case. If the edit was successfull, the program will show a message indicating that the value was changed from `0.7->0.5`.
For an edit file, simply drop the `-e` and put one edit per line:
### edit_file.txt
0x11C28[0]=0.5
0x11C28[1]=0.2
...
## Types of Member Variables
Structures can have different types of member variables:
- `float` - दशमलव बिंदु के साथ दशमलव मान निर्दिष्ट करें (जैसे, 0.5).
- `int` - बिना दशमलव बिंदु के पूर्णांक मान निर्दिष्ट करें (जैसे, 42).
- `sid` (स्ट्रिंग पहचानकर्ता) - (नीचे और जानकारी)
- `string` - वर्तमान में प्रतिस्थापन के लिए समर्थित नहीं है
- `structure` - पॉइंटर को प्रतिस्थापित करके (नीचे और जानकारी)
### Replacing sid by name lookup:
`-e 0xABC[5]=ellie`
This looks for the value "ellie" in the current sidbase. If it doesn't exist, a warning is issued and no edit is applied. If the value is found, the actual hash value (a large number) will replace the current value at the member variable.
### Replacing sid by direct manual hash override:
`-e 0xABC[5]=#XXXXXXXXXXXXXXXX`
The # indicates a raw hash value, which will be applied directly without a lookup.
### Replacing member structures
If a structure contains another structure as a member, you can replace the entire member structure by assigning it the address of another structure.
For example, suppose you have the following:```c++
[4] weapon-gameplay-def [0x0C523] {
...
[7] firearm-gameplay-def [0x11C28] {
...
}
}
तो weapon-gameplay-def में एक firearm-gameplay-def होता है।
weapon-gameplay-def के अंदर firearm-gameplay-def को पते 0x0ABC पर स्थित एक भिन्न firearm-gameplay-def से बदलने के लिए, संपादन इस प्रकार होगा:
-e 0x11C28[7]=0x0ABC
VS Code कस्टम भाषाओं में सिंटैक्स हाइलाइटिंग जोड़ने के लिए कस्टम एक्सटेंशन बनाने का समर्थन करता है। dconstruct एक .vsix फ़ाइल के साथ आता है जो .dcpl फ़ाइल एक्सटेंशन के लिए यह समर्थन जोड़ता है। चूंकि यह एक एकल-उपयोग भाषा है जो वास्तव में दैनिक प्रोग्रामिंग के लिए नहीं है, मैं एक्सटेंशन को मार्केटप्लेस पर अपलोड नहीं कर रहा हूं, और इसके बजाय इसे एक कच्ची .vsix फ़ाइल के रूप में शिप कर रहा हूं। अपने VS Code में इस एक्सटेंशन को इंस्टॉल करने के लिए, निम्न कमांड चलाएं:```shell
code --install-extension <path/to/extension/dcpl-lint-0.0.1.vsix>
या CTRL+SHIFT+P के साथ कमांड पैलेट खोलें और "Install extension via VSIX" टाइप करें और .vsix फाइल चुनें।
इसके बाद, आपका .dcpl कोड कुछ इस तरह दिखना चाहिए:

# ज्ञात समस्याएँ
डीकंपाइलर वर्तमान में 100% पूर्ण नहीं है और इसलिए एक "प्रायोगिक" स्थिति में है। यदि आपको डीकंपाइलेशन के दौरान चेतावनियाँ मिलती हैं, तो चिंता न करें क्योंकि ये फ़ंक्शन वर्तमान में समर्थित नहीं हैं, लेकिन उम्मीद है कि भविष्य में होंगे। इनके साथ, वर्तमान में और भी ज्ञात समस्याएँ हैं:
- भारी शॉर्ट-सर्किटिंग वाले एकल-अभिव्यक्ति फ़ंक्शन (विशेष रूप से स्ट्रक्ट के अंदर वाले) अभी तक लागू नहीं किए गए हैं। मैंने इनके लिए एल्गोरिदम पर काम शुरू कर दिया है, लेकिन मुझे नहीं पता कि इसे पूरा होने में कितना समय लगेगा, हालाँकि यह प्राथमिकताओं की सूची में ऊपर है।
- कुछ प्रकार गलत हैं, विशेष रूप से तर्क प्रकार।
- if/else कथनों में खाली if ब्लॉक अजीब इंडेंटेशन का कारण बन सकते हैं। यह फिर से हमेशा मेरी गलती नहीं है, क्योंकि कुछ ऐसी शाखाएँ हैं जो वास्तव में कोई वास्तविक कार्य नहीं करती हैं, जिनका पता लगाना मुश्किल है।
इनके साथ, कुछ ऐसी समस्याएँ हैं जो शायद ठीक नहीं होंगी:
- जब यह ज्ञात नहीं होता कि कोई फ़ंक्शन void है या नहीं, तो कचरा वापस करना।
- बहुत सारा अनावश्यक कोड।
# नियोजित सुविधाएँ
- एक पूर्ण Racket और Python आउटपुट प्रारूप।
# विशेष धन्यवाद
- **icemesh** – DC-फ़ाइलों के लिए अंतर्निहित [संरचनाएँ](https://github.com/icemesh/dc/tree/main/t2) और [उनके डिस्सेम्बलर](https://github.com/icemesh/t2-dc-disasm) प्रदान करने के लिए, जो काफी हद तक प्रेरणा के रूप में कार्य करते थे।
- **Specilizer** – उनके DC-Tool के लिए, जो इस प्रोग्राम के लिए भी प्रेरणा थी।
- **uxh** – स्क्रिप्टिंग ज्ञान के लिए।
- **bigdragon** और **Wedge** बीटा परीक्षण के लिए।
- संपूर्ण मॉडिंग Discord समुदाय – मित्रवत और सहायक होने के लिए।
## सहायता
मेरे सभी उपकरण और मॉड हमेशा 100% मुफ्त रहेंगे, लेकिन इस तरह के कार्यक्रमों में बहुत मेहनत लगती है।
यदि आप मेरा समर्थन करना चाहते हैं, तो आप मेरे Ko-fi पर जा सकते हैं:
[](https://ko-fi.com/deepquantum)
## लाइसेंस
इस मॉड का उपयोग करके आप जो फ़ाइलें बनाते हैं, वे पूरी तरह से आपकी हैं और आप उनके साथ जो चाहें करने के लिए स्वतंत्र हैं। क्रेडिट की सराहना की जाएगी लेकिन कड़ाई से आवश्यक नहीं है।
यह प्रोग्राम स्वयं
[क्रिएटिव कॉमन्स एट्रिब्यूशन-नॉनकमर्शियल-नोडेरिवेटिव्स 4.0 इंटरनेशनल लाइसेंस](https://creativecommons.org/licenses/by-nc-nd/4.0/) के तहत लाइसेंस प्राप्त है।
इसका मतलब है कि आप क्रेडिट देने पर दूसरों के साथ प्रोग्राम साझा कर सकते हैं, लेकिन वर्तमान में आप इसे संशोधित नहीं कर सकते और न ही इसका मुद्रीकरण कर सकते हैं।