Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Y
ygopro-deck-encode
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
MyCard
ygopro-deck-encode
Commits
2c6d6fc6
You need to sign in or sign up before continuing.
Commit
2c6d6fc6
authored
May 21, 2025
by
nanahira
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add ydke and update doc
parent
439c6df1
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
169 additions
and
13 deletions
+169
-13
README.md
README.md
+8
-0
index.ts
index.ts
+28
-7
package-lock.json
package-lock.json
+9
-1
package.json
package.json
+2
-1
src/ydke.ts
src/ydke.ts
+60
-0
src/ygom.ts
src/ygom.ts
+2
-2
tests/sample.spec.ts
tests/sample.spec.ts
+23
-2
tests/ydke.spec.ts
tests/ydke.spec.ts
+37
-0
No files found.
README.md
View file @
2c6d6fc6
...
...
@@ -15,6 +15,14 @@ const anotherDeck = YGOProDeck.fromEncodedString(code); // decode it back
const
ydk
=
deck
.
toYdkString
();
// YDK format
const
yetAnotherDeck
=
YGOProDeck
.
fromYdkString
(
ydk
);
// decode it back
const
ydke
=
deck
.
toYdkeURL
();
const
yetAnotherDeck2
=
YGOProDeck
.
fromYdkeURL
(
ydke
);
// decode it back
const
ygomobileDeckUrl
=
deck
.
toYGOMobileDeckURL
();
// YGOMobile Deck URL
const
yetAnotherDeck3
=
YGOProDeck
.
fromYGOMobileDeckURL
(
ygomobileDeckUrl
);
// decode it back
const
updateDeckPayload
=
deck
.
toUpdateDeckPayload
();
// payload for MSG_UPDATE_DECK
```
...
...
index.ts
View file @
2c6d6fc6
import
{
fromBase64Url
,
toBase64Url
}
from
'
./src/base64
'
;
import
{
BufferWriter
,
countItems
}
from
'
./src/utils
'
;
import
{
fromYGOMobileDeckUri
,
toYGOMobileDeckUri
}
from
'
./src/ygom
'
;
import
{
fromYdkeURL
,
toYdkeURL
}
from
'
./src/ydke
'
;
import
{
fromYGOMobileDeckURL
,
toYGOMobileDeckURL
}
from
'
./src/ygom
'
;
export
default
class
YGOProDeck
{
main
:
number
[]
=
[];
...
...
@@ -113,8 +114,8 @@ export default class YGOProDeck {
return
writer
.
buffer
;
}
fromYGOMobileDeckU
ri
(
uri
:
string
):
YGOProDeck
{
const
parsed
=
fromYGOMobileDeckU
ri
(
uri
);
fromYGOMobileDeckU
RL
(
uri
:
string
):
YGOProDeck
{
const
parsed
=
fromYGOMobileDeckU
RL
(
uri
);
this
.
main
=
parsed
.
main
;
this
.
extra
=
parsed
.
extra
;
this
.
side
=
parsed
.
side
;
...
...
@@ -122,13 +123,33 @@ export default class YGOProDeck {
return
this
;
}
static
fromYGOMobileDeckU
ri
(
uri
:
string
):
YGOProDeck
{
return
new
YGOProDeck
().
fromYGOMobileDeckU
ri
(
uri
);
static
fromYGOMobileDeckU
RL
(
uri
:
string
):
YGOProDeck
{
return
new
YGOProDeck
().
fromYGOMobileDeckU
RL
(
uri
);
}
toYGOMobileDeckU
ri
():
string
{
return
toYGOMobileDeckU
ri
(
this
.
main
,
this
.
extra
,
this
.
side
,
this
.
name
&&
{
toYGOMobileDeckU
RL
():
string
{
return
toYGOMobileDeckU
RL
(
this
.
main
,
this
.
extra
,
this
.
side
,
this
.
name
&&
{
name
:
this
.
name
,
});
}
fromYdkeURL
(
uri
:
string
):
YGOProDeck
{
const
parsed
=
fromYdkeURL
(
uri
);
this
.
main
=
parsed
.
main
;
this
.
extra
=
parsed
.
extra
;
this
.
side
=
parsed
.
side
;
return
this
;
}
static
fromYdkeURL
(
uri
:
string
):
YGOProDeck
{
return
new
YGOProDeck
().
fromYdkeURL
(
uri
);
}
toYdkeURL
():
string
{
return
toYdkeURL
({
main
:
this
.
main
,
extra
:
this
.
extra
,
side
:
this
.
side
,
});
}
}
package-lock.json
View file @
2c6d6fc6
...
...
@@ -22,7 +22,8 @@
"prettier"
:
"^2.8.4"
,
"rimraf"
:
"^4.1.2"
,
"ts-jest"
:
"^29.0.5"
,
"typescript"
:
"^4.9.5"
"typescript"
:
"^4.9.5"
,
"ydke"
:
"^1.1.0"
}
},
"node_modules/@ampproject/remapping"
:
{
...
...
@@ -5168,6 +5169,13 @@
"node"
:
">=12"
}
},
"node_modules/ydke"
:
{
"version"
:
"1.1.0"
,
"resolved"
:
"https://registry.npmjs.org/ydke/-/ydke-1.1.0.tgz"
,
"integrity"
:
"sha512-q6EbAMtup1stTOER9/PNLH/uDQ1guYmiTU/+jn1BSePmkfvm9Rky49byQDNqYQjwrSXoLaoygkQMGIwNQRr+cg=="
,
"dev"
:
true
,
"license"
:
"LGPL-3.0+"
},
"node_modules/yocto-queue"
:
{
"version"
:
"0.1.0"
,
"resolved"
:
"https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz"
,
...
...
package.json
View file @
2c6d6fc6
...
...
@@ -56,6 +56,7 @@
"
prettier
"
:
"
^2.8.4
"
,
"
rimraf
"
:
"
^4.1.2
"
,
"
ts-jest
"
:
"
^29.0.5
"
,
"
typescript
"
:
"
^4.9.5
"
"
typescript
"
:
"
^4.9.5
"
,
"
ydke
"
:
"
^1.1.0
"
}
}
src/ydke.ts
0 → 100644
View file @
2c6d6fc6
// ydke.ts
export
interface
TypedDeck
{
main
:
number
[];
extra
:
number
[];
side
:
number
[];
}
function
base64ToUint32Array
(
base64
:
string
):
number
[]
{
const
binary
=
atob
(
base64
);
const
bytes
=
new
Uint8Array
(
binary
.
length
);
for
(
let
i
=
0
;
i
<
binary
.
length
;
i
++
)
{
bytes
[
i
]
=
binary
.
charCodeAt
(
i
);
}
const
view
=
new
DataView
(
bytes
.
buffer
);
const
result
:
number
[]
=
[];
for
(
let
i
=
0
;
i
<
bytes
.
length
;
i
+=
4
)
{
result
.
push
(
view
.
getUint32
(
i
,
true
));
// little-endian
}
return
result
;
}
function
uint32ArrayToBase64
(
data
:
number
[]):
string
{
const
buffer
=
new
ArrayBuffer
(
data
.
length
*
4
);
const
view
=
new
DataView
(
buffer
);
data
.
forEach
((
val
,
i
)
=>
view
.
setUint32
(
i
*
4
,
val
,
true
));
const
bytes
=
new
Uint8Array
(
buffer
);
let
binary
=
''
;
for
(
let
i
=
0
;
i
<
bytes
.
length
;
i
++
)
{
binary
+=
String
.
fromCharCode
(
bytes
[
i
]);
}
return
btoa
(
binary
);
}
export
function
toYdkeURL
(
deck
:
TypedDeck
):
string
{
return
(
'
ydke://
'
+
uint32ArrayToBase64
(
deck
.
main
)
+
'
!
'
+
uint32ArrayToBase64
(
deck
.
extra
)
+
'
!
'
+
uint32ArrayToBase64
(
deck
.
side
)
+
'
!
'
);
}
export
function
fromYdkeURL
(
ydke
:
string
):
TypedDeck
{
if
(
!
ydke
.
startsWith
(
'
ydke://
'
))
{
throw
new
Error
(
'
Invalid ydke:// URI
'
);
}
const
[
mainStr
,
extraStr
,
sideStr
]
=
ydke
.
slice
(
7
).
split
(
'
!
'
);
if
(
mainStr
===
undefined
||
extraStr
===
undefined
||
sideStr
===
undefined
)
{
throw
new
Error
(
'
Incomplete ydke:// URI
'
);
}
return
{
main
:
base64ToUint32Array
(
mainStr
),
extra
:
base64ToUint32Array
(
extraStr
),
side
:
base64ToUint32Array
(
sideStr
),
};
}
src/ygom.ts
View file @
2c6d6fc6
...
...
@@ -47,7 +47,7 @@ function countUnique(cards: number[]): number {
// === 主函数 ===
export
function
toYGOMobileDeckU
ri
(
export
function
toYGOMobileDeckU
RL
(
main
:
number
[],
extra
:
number
[],
side
:
number
[],
...
...
@@ -80,7 +80,7 @@ export function toYGOMobileDeckUri(
}
export
function
fromYGOMobileDeckU
ri
(
uri
:
string
):
{
export
function
fromYGOMobileDeckU
RL
(
uri
:
string
):
{
main
:
number
[];
extra
:
number
[];
side
:
number
[];
...
...
tests/sample.spec.ts
View file @
2c6d6fc6
...
...
@@ -54,15 +54,36 @@ describe('Sample test.', () => {
it
(
'
should encode and decode ygomobile
'
,
()
=>
{
const
uri
=
'
http://deck.ourygo.top?name=%E7%99%BD%E9%93%B6%E5%9F%8E%E7%A0%81&ygotype=deck&v=1&d=J-xK4Mka02AuEAMf2dV6mj7aRemuJNQJK8BwrcEYh0MqOJqBJSgYqUwxPEVhOG8R18WWVKmzkT-xEdwxbmGVkkOdrVIpufaYI3Hs8oOrcya8Bi40h9G79iFW80rq-o6P-AHsusPY5nmvHLol0DIqEykESVlf6VSbxVJp-j7XZtTE0XvmJW80rqH28R4rgyRovOusVJzbutenYFBA_cyK6d3UWcQkJQlLjaroWavH-INFA56k5DQNWOQ1gpvxrKVBLgEk1olpolKmSgriramLlgtBK1EQ6C6oi94ZyHe7N6T7mqE6peds7mahrORP6A
'
;
const
deck
=
new
YGOProDeck
().
fromYGOMobileDeckU
ri
(
uri
);
const
deck
=
new
YGOProDeck
().
fromYGOMobileDeckU
RL
(
uri
);
expect
(
deck
.
main
).
toHaveLength
(
58
);
expect
(
deck
.
extra
).
toHaveLength
(
15
);
expect
(
deck
.
side
).
toHaveLength
(
15
);
expect
(
deck
.
main
[
0
]).
toBe
(
22812963
);
expect
(
deck
.
extra
[
0
]).
toBe
(
12381100
);
expect
(
deck
.
side
[
0
]).
toBe
(
20292186
);
const
uri2
=
deck
.
toYGOMobileDeckU
ri
();
const
uri2
=
deck
.
toYGOMobileDeckU
RL
();
expect
(
uri2
).
toBe
(
uri
);
})
it
(
'
should encode and decode ydke URL
'
,
()
=>
{
const
deck
=
new
YGOProDeck
();
deck
.
main
.
push
(
111111
);
deck
.
main
.
push
(
111111
);
deck
.
main
.
push
(
111111
);
deck
.
main
.
push
(
222222
);
deck
.
main
.
push
(
333333
);
deck
.
extra
.
push
(
444444
);
deck
.
extra
.
push
(
555555
);
deck
.
side
.
push
(
666666
);
const
uri
=
deck
.
toYdkeURL
();
expect
(
uri
.
startsWith
(
'
ydke://
'
)).
toBe
(
true
);
const
decoded
=
new
YGOProDeck
().
fromYdkeURL
(
uri
);
expect
(
decoded
.
main
).
toStrictEqual
(
deck
.
main
);
expect
(
decoded
.
extra
).
toStrictEqual
(
deck
.
extra
);
expect
(
decoded
.
side
).
toStrictEqual
(
deck
.
side
);
});
});
tests/ydke.spec.ts
0 → 100644
View file @
2c6d6fc6
import
YGOProDeck
from
'
..
'
;
import
*
as
ydkejs
from
'
ydke
'
;
describe
(
'
YDKE interoperability test
'
,
()
=>
{
const
main
=
[
1000
,
1000
,
1000
,
2000
,
2000
,
3000
];
const
extra
=
[
4000
,
5000
];
const
side
=
[
6000
];
it
(
'
should encode with ygopro-deck-encode and decode with ydke.js
'
,
()
=>
{
const
deck
=
new
YGOProDeck
();
deck
.
main
=
[...
main
];
deck
.
extra
=
[...
extra
];
deck
.
side
=
[...
side
];
const
uri
=
deck
.
toYdkeURL
();
const
decoded
=
ydkejs
.
parseURL
(
uri
);
expect
(
Array
.
from
(
decoded
.
main
)).
toStrictEqual
(
main
);
expect
(
Array
.
from
(
decoded
.
extra
)).
toStrictEqual
(
extra
);
expect
(
Array
.
from
(
decoded
.
side
)).
toStrictEqual
(
side
);
});
it
(
'
should encode with ydke.js and decode with ygopro-deck-encode
'
,
()
=>
{
const
typedDeck
:
ydkejs
.
TypedDeck
=
{
main
:
new
Uint32Array
(
main
),
extra
:
new
Uint32Array
(
extra
),
side
:
new
Uint32Array
(
side
),
};
const
uri
=
ydkejs
.
toURL
(
typedDeck
);
const
decoded
=
new
YGOProDeck
().
fromYdkeURL
(
uri
);
expect
(
decoded
.
main
).
toStrictEqual
(
main
);
expect
(
decoded
.
extra
).
toStrictEqual
(
extra
);
expect
(
decoded
.
side
).
toStrictEqual
(
side
);
});
});
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment