Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
ziqian zhang
Grasscutter
Commits
7925d1cd
Commit
7925d1cd
authored
Apr 17, 2022
by
Melledy
Browse files
Initial commit
parents
Changes
354
Show whitespace changes
Inline
Side-by-side
src/main/java/emu/grasscutter/server/packet/send/PacketWorldDataNotify.java
0 → 100644
View file @
7925d1cd
package
emu.grasscutter.server.packet.send
;
import
emu.grasscutter.game.World
;
import
emu.grasscutter.net.packet.GenshinPacket
;
import
emu.grasscutter.net.packet.PacketOpcodes
;
import
emu.grasscutter.net.proto.PropValueOuterClass.PropValue
;
import
emu.grasscutter.net.proto.WorldDataNotifyOuterClass.WorldDataNotify
;
public
class
PacketWorldDataNotify
extends
GenshinPacket
{
public
PacketWorldDataNotify
(
World
world
)
{
super
(
PacketOpcodes
.
WorldDataNotify
);
int
worldLevel
=
world
.
getWorldLevel
();
int
isMp
=
world
.
isMultiplayer
()
?
1
:
0
;
WorldDataNotify
proto
=
WorldDataNotify
.
newBuilder
()
.
putWorldPropMap
(
1
,
PropValue
.
newBuilder
().
setType
(
1
).
setIval
(
worldLevel
).
setVal
(
worldLevel
).
build
())
.
putWorldPropMap
(
2
,
PropValue
.
newBuilder
().
setType
(
2
).
setIval
(
isMp
).
setVal
(
isMp
).
build
())
.
build
();
this
.
setData
(
proto
);
}
}
src/main/java/emu/grasscutter/server/packet/send/PacketWorldPlayerDieNotify.java
0 → 100644
View file @
7925d1cd
package
emu.grasscutter.server.packet.send
;
import
emu.grasscutter.net.packet.GenshinPacket
;
import
emu.grasscutter.net.packet.PacketOpcodes
;
import
emu.grasscutter.net.proto.PlayerDieTypeOuterClass.PlayerDieType
;
import
emu.grasscutter.net.proto.WorldPlayerDieNotifyOuterClass.WorldPlayerDieNotify
;
public
class
PacketWorldPlayerDieNotify
extends
GenshinPacket
{
public
PacketWorldPlayerDieNotify
(
PlayerDieType
playerDieType
,
int
killerId
)
{
super
(
PacketOpcodes
.
WorldPlayerDieNotify
);
WorldPlayerDieNotify
proto
=
WorldPlayerDieNotify
.
newBuilder
()
.
setDieType
(
playerDieType
)
.
setMonsterId
(
killerId
)
.
build
();
this
.
setData
(
proto
);
}
}
src/main/java/emu/grasscutter/server/packet/send/PacketWorldPlayerInfoNotify.java
0 → 100644
View file @
7925d1cd
package
emu.grasscutter.server.packet.send
;
import
emu.grasscutter.game.GenshinPlayer
;
import
emu.grasscutter.game.World
;
import
emu.grasscutter.net.packet.GenshinPacket
;
import
emu.grasscutter.net.packet.PacketOpcodes
;
import
emu.grasscutter.net.proto.WorldPlayerInfoNotifyOuterClass.WorldPlayerInfoNotify
;
public
class
PacketWorldPlayerInfoNotify
extends
GenshinPacket
{
public
PacketWorldPlayerInfoNotify
(
World
world
)
{
super
(
PacketOpcodes
.
WorldPlayerInfoNotify
);
WorldPlayerInfoNotify
.
Builder
proto
=
WorldPlayerInfoNotify
.
newBuilder
();
for
(
int
i
=
0
;
i
<
world
.
getPlayers
().
size
();
i
++)
{
GenshinPlayer
p
=
world
.
getPlayers
().
get
(
i
);
proto
.
addPlayerInfoList
(
p
.
getOnlinePlayerInfo
());
proto
.
addPlayerUidList
(
p
.
getId
());
}
this
.
setData
(
proto
.
build
());
}
}
src/main/java/emu/grasscutter/server/packet/send/PacketWorldPlayerLocationNotify.java
0 → 100644
View file @
7925d1cd
package
emu.grasscutter.server.packet.send
;
import
emu.grasscutter.game.GenshinPlayer
;
import
emu.grasscutter.game.World
;
import
emu.grasscutter.net.packet.GenshinPacket
;
import
emu.grasscutter.net.packet.PacketOpcodes
;
import
emu.grasscutter.net.proto.WorldPlayerLocationNotifyOuterClass.WorldPlayerLocationNotify
;
public
class
PacketWorldPlayerLocationNotify
extends
GenshinPacket
{
public
PacketWorldPlayerLocationNotify
(
World
world
)
{
super
(
PacketOpcodes
.
WorldPlayerLocationNotify
);
WorldPlayerLocationNotify
.
Builder
proto
=
WorldPlayerLocationNotify
.
newBuilder
();
for
(
GenshinPlayer
p
:
world
.
getPlayers
())
{
proto
.
addPlayerLocList
(
p
.
getPlayerLocationInfo
());
}
this
.
setData
(
proto
);
}
}
src/main/java/emu/grasscutter/server/packet/send/PacketWorldPlayerRTTNotify.java
0 → 100644
View file @
7925d1cd
package
emu.grasscutter.server.packet.send
;
import
emu.grasscutter.game.GenshinPlayer
;
import
emu.grasscutter.game.World
;
import
emu.grasscutter.net.packet.GenshinPacket
;
import
emu.grasscutter.net.packet.PacketOpcodes
;
import
emu.grasscutter.net.proto.PlayerRTTInfoOuterClass.PlayerRTTInfo
;
import
emu.grasscutter.net.proto.WorldPlayerRTTNotifyOuterClass.WorldPlayerRTTNotify
;
public
class
PacketWorldPlayerRTTNotify
extends
GenshinPacket
{
public
PacketWorldPlayerRTTNotify
(
World
world
)
{
super
(
PacketOpcodes
.
WorldPlayerRTTNotify
);
WorldPlayerRTTNotify
.
Builder
proto
=
WorldPlayerRTTNotify
.
newBuilder
();
for
(
GenshinPlayer
player
:
world
.
getPlayers
())
{
proto
.
addPlayerRttList
(
PlayerRTTInfo
.
newBuilder
()
.
setUid
(
player
.
getId
())
.
setRtt
(
10
)
// TODO - put player ping here
);
}
this
.
setData
(
proto
);
}
}
src/main/java/emu/grasscutter/tools/Dumpers.java
0 → 100644
View file @
7925d1cd
package
emu.grasscutter.tools
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.List
;
import
emu.grasscutter.game.props.OpenState
;
import
emu.grasscutter.net.proto.GetGachaInfoRspOuterClass.GetGachaInfoRsp
;
import
emu.grasscutter.net.proto.GetShopRspOuterClass.GetShopRsp
;
import
emu.grasscutter.net.proto.OpenStateUpdateNotifyOuterClass.OpenStateUpdateNotify
;
import
emu.grasscutter.utils.FileUtils
;
public
class
Dumpers
{
public
static
void
extractBanner
(
byte
[]
data
)
throws
Exception
{
GetGachaInfoRsp
proto
=
GetGachaInfoRsp
.
parseFrom
(
data
);
System
.
out
.
println
(
proto
);
}
public
static
void
extractShop
(
byte
[]
data
)
throws
Exception
{
GetShopRsp
proto
=
GetShopRsp
.
parseFrom
(
data
);
System
.
out
.
println
(
proto
);
}
public
static
void
dumpOpenStates
(
byte
[]
data
)
throws
Exception
{
OpenStateUpdateNotify
proto
=
OpenStateUpdateNotify
.
parseFrom
(
data
);
List
<
Integer
>
list
=
new
ArrayList
<>(
proto
.
getOpenStateMap
().
keySet
());
Collections
.
sort
(
list
);
for
(
int
key
:
list
)
{
System
.
out
.
println
(
OpenState
.
getTypeByValue
(
key
)
+
" : "
+
key
);
}
}
}
src/main/java/emu/grasscutter/tools/Tools.java
0 → 100644
View file @
7925d1cd
package
emu.grasscutter.tools
;
import
java.io.FileReader
;
import
java.io.FileWriter
;
import
java.io.PrintWriter
;
import
java.time.LocalDateTime
;
import
java.time.format.DateTimeFormatter
;
import
java.util.Collections
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.stream.Collectors
;
import
com.google.gson.reflect.TypeToken
;
import
emu.grasscutter.GenshinConstants
;
import
emu.grasscutter.Grasscutter
;
import
emu.grasscutter.data.GenshinData
;
import
emu.grasscutter.data.ResourceLoader
;
import
emu.grasscutter.data.def.AvatarData
;
import
emu.grasscutter.data.def.ItemData
;
import
emu.grasscutter.data.def.MonsterData
;
public
class
Tools
{
@SuppressWarnings
(
"deprecation"
)
public
static
void
createGmHandbook
()
throws
Exception
{
ResourceLoader
.
loadResources
();
Map
<
Long
,
String
>
map
;
try
(
FileReader
fileReader
=
new
FileReader
(
Grasscutter
.
getConfig
().
RESOURCE_FOLDER
+
"TextMapEN.json"
))
{
map
=
Grasscutter
.
getGsonFactory
().
fromJson
(
fileReader
,
new
TypeToken
<
Map
<
Long
,
String
>>()
{}.
getType
());
}
List
<
Integer
>
list
;
String
fileName
=
"./GM Handbook.txt"
;
try
(
FileWriter
fileWriter
=
new
FileWriter
(
fileName
);
PrintWriter
writer
=
new
PrintWriter
(
fileWriter
))
{
DateTimeFormatter
dtf
=
DateTimeFormatter
.
ofPattern
(
"yyyy/MM/dd HH:mm:ss"
);
LocalDateTime
now
=
LocalDateTime
.
now
();
writer
.
println
(
"// Genshin Impact "
+
GenshinConstants
.
VERSION
+
" GM Handbook"
);
writer
.
println
(
"// Created "
+
dtf
.
format
(
now
)
+
System
.
lineSeparator
()
+
System
.
lineSeparator
());
list
=
GenshinData
.
getAvatarDataMap
().
keySet
().
stream
().
collect
(
Collectors
.
toList
());
Collections
.
sort
(
list
);
writer
.
println
(
"// Avatars"
);
for
(
Integer
id
:
list
)
{
AvatarData
data
=
GenshinData
.
getAvatarDataMap
().
get
(
id
);
writer
.
println
(
data
.
getId
()
+
" : "
+
map
.
get
(
data
.
getNameTextMapHash
()));
}
writer
.
println
();
list
=
GenshinData
.
getItemDataMap
().
keySet
().
stream
().
collect
(
Collectors
.
toList
());
Collections
.
sort
(
list
);
writer
.
println
(
"// Items"
);
for
(
Integer
id
:
list
)
{
ItemData
data
=
GenshinData
.
getItemDataMap
().
get
(
id
);
writer
.
println
(
data
.
getId
()
+
" : "
+
map
.
get
(
data
.
getNameTextMapHash
()));
}
writer
.
println
();
writer
.
println
(
"// Monsters"
);
list
=
GenshinData
.
getMonsterDataMap
().
keySet
().
stream
().
collect
(
Collectors
.
toList
());
Collections
.
sort
(
list
);
for
(
Integer
id
:
list
)
{
MonsterData
data
=
GenshinData
.
getMonsterDataMap
().
get
(
id
);
writer
.
println
(
data
.
getId
()
+
" : "
+
map
.
get
(
data
.
getNameTextMapHash
()));
}
}
Grasscutter
.
getLogger
().
info
(
"GM Handbook generated!"
);
}
}
src/main/java/emu/grasscutter/utils/Crypto.java
0 → 100644
View file @
7925d1cd
package
emu.grasscutter.utils
;
import
java.security.SecureRandom
;
import
java.util.Base64
;
import
emu.grasscutter.Grasscutter
;
import
emu.grasscutter.net.proto.GetPlayerTokenRspOuterClass.GetPlayerTokenRsp
;
import
emu.grasscutter.net.proto.QueryCurrRegionHttpRspOuterClass.QueryCurrRegionHttpRsp
;
public
class
Crypto
{
private
static
SecureRandom
secureRandom
=
new
SecureRandom
();
public
static
final
long
ENCRYPT_SEED
=
Long
.
parseUnsignedLong
(
"11468049314633205968"
);
public
static
byte
[]
ENCRYPT_SEED_BUFFER
=
new
byte
[
0
];
public
static
byte
[]
DISPATCH_KEY
;
public
static
byte
[]
ENCRYPT_KEY
;
public
static
void
loadKeys
()
{
DISPATCH_KEY
=
FileUtils
.
read
(
Grasscutter
.
getConfig
().
KEY_FOLDER
+
"dispatchKey.bin"
);
ENCRYPT_KEY
=
FileUtils
.
read
(
Grasscutter
.
getConfig
().
KEY_FOLDER
+
"secretKey.bin"
);
ENCRYPT_SEED_BUFFER
=
FileUtils
.
read
(
Grasscutter
.
getConfig
().
KEY_FOLDER
+
"secretKeyBuffer.bin"
);
}
public
static
void
xor
(
byte
[]
packet
,
byte
[]
key
)
{
try
{
for
(
int
i
=
0
;
i
<
packet
.
length
;
i
++)
{
packet
[
i
]
^=
key
[
i
%
key
.
length
];
}
}
catch
(
Exception
e
)
{
Grasscutter
.
getLogger
().
error
(
"Crypto error."
,
e
);
}
}
public
static
void
extractSecretKeyBuffer
(
byte
[]
data
)
{
try
{
GetPlayerTokenRsp
p
=
GetPlayerTokenRsp
.
parseFrom
(
data
);
FileUtils
.
write
(
Grasscutter
.
getConfig
().
KEY_FOLDER
+
"secretKeyBuffer.bin"
,
p
.
getSecretKeyBuffer
().
toByteArray
());
Grasscutter
.
getLogger
().
info
(
"Secret Key: "
+
p
.
getSecretKey
());
}
catch
(
Exception
e
)
{
// TODO Auto-generated catch block
e
.
printStackTrace
();
}
}
public
static
void
extractDispatchSeed
(
String
data
)
{
try
{
QueryCurrRegionHttpRsp
p
=
QueryCurrRegionHttpRsp
.
parseFrom
(
Base64
.
getDecoder
().
decode
(
data
));
FileUtils
.
write
(
Grasscutter
.
getConfig
().
KEY_FOLDER
+
"dispatchSeed.bin"
,
p
.
getRegionInfo
().
getSecretKey
().
toByteArray
());
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
}
public
static
byte
[]
createSessionKey
(
int
length
)
{
byte
[]
bytes
=
new
byte
[
length
];
secureRandom
.
nextBytes
(
bytes
);
return
bytes
;
}
}
src/main/java/emu/grasscutter/utils/FileUtils.java
0 → 100644
View file @
7925d1cd
package
emu.grasscutter.utils
;
import
java.io.File
;
import
java.io.IOException
;
import
java.nio.file.Files
;
import
java.nio.file.Path
;
import
java.nio.file.Paths
;
public
class
FileUtils
{
public
static
void
write
(
String
dest
,
byte
[]
bytes
)
{
Path
path
=
Paths
.
get
(
dest
);
try
{
Files
.
write
(
path
,
bytes
);
}
catch
(
IOException
e
)
{
// TODO Auto-generated catch block
e
.
printStackTrace
();
}
}
public
static
byte
[]
read
(
String
dest
)
{
return
read
(
Paths
.
get
(
dest
));
}
public
static
byte
[]
read
(
Path
path
)
{
try
{
return
Files
.
readAllBytes
(
path
);
}
catch
(
IOException
e
)
{
// TODO Auto-generated catch block
e
.
printStackTrace
();
}
return
new
byte
[
0
];
}
public
static
byte
[]
read
(
File
file
)
{
return
read
(
file
.
getPath
());
}
public
static
String
getFilenameWithoutPath
(
String
fileName
)
{
if
(
fileName
.
indexOf
(
"."
)
>
0
)
{
return
fileName
.
substring
(
0
,
fileName
.
lastIndexOf
(
"."
));
}
else
{
return
fileName
;
}
}
}
src/main/java/emu/grasscutter/utils/Position.java
0 → 100644
View file @
7925d1cd
package
emu.grasscutter.utils
;
import
java.io.Serializable
;
import
emu.grasscutter.net.proto.VectorOuterClass.Vector
;
public
class
Position
implements
Serializable
{
private
static
final
long
serialVersionUID
=
-
2001232313615923575L
;
private
float
x
;
private
float
y
;
private
float
z
;
public
Position
()
{
}
public
Position
(
float
x
,
float
y
)
{
set
(
x
,
y
);
}
public
Position
(
float
x
,
float
y
,
float
z
)
{
set
(
x
,
y
,
z
);
}
public
Position
(
String
p
)
{
String
[]
split
=
p
.
split
(
","
);
if
(
split
.
length
>=
2
)
{
this
.
x
=
Float
.
parseFloat
(
split
[
0
]);
this
.
y
=
Float
.
parseFloat
(
split
[
1
]);
}
if
(
split
.
length
>=
3
)
{
this
.
z
=
Float
.
parseFloat
(
split
[
2
]);
}
}
public
Position
(
Vector
vector
)
{
this
.
set
(
vector
);
}
public
Position
(
Position
pos
)
{
this
.
set
(
pos
);
}
public
float
getX
()
{
return
x
;
}
public
void
setX
(
float
x
)
{
this
.
x
=
x
;
}
public
float
getZ
()
{
return
z
;
}
public
void
setZ
(
float
z
)
{
this
.
z
=
z
;
}
public
float
getY
()
{
return
y
;
}
public
void
setY
(
float
y
)
{
this
.
y
=
y
;
}
public
Position
set
(
float
x
,
float
y
)
{
this
.
x
=
x
;
this
.
y
=
y
;
return
this
;
}
// Deep copy
public
Position
set
(
Position
pos
)
{
return
this
.
set
(
pos
.
getX
(),
pos
.
getY
(),
pos
.
getZ
());
}
public
Position
set
(
Vector
pos
)
{
return
this
.
set
(
pos
.
getX
(),
pos
.
getY
(),
pos
.
getZ
());
}
public
Position
set
(
float
x
,
float
y
,
float
z
)
{
this
.
x
=
x
;
this
.
y
=
y
;
this
.
z
=
z
;
return
this
;
}
public
Position
add
(
Position
add
)
{
this
.
x
+=
add
.
getX
();
this
.
y
+=
add
.
getY
();
this
.
z
+=
add
.
getZ
();
return
this
;
}
public
Position
addX
(
float
d
)
{
this
.
x
+=
d
;
return
this
;
}
public
Position
addY
(
float
d
)
{
this
.
y
+=
d
;
return
this
;
}
public
Position
addZ
(
float
d
)
{
this
.
z
+=
d
;
return
this
;
}
public
Position
subtract
(
Position
sub
)
{
this
.
x
-=
sub
.
getX
();
this
.
y
-=
sub
.
getY
();
this
.
z
-=
sub
.
getZ
();
return
this
;
}
/** In radians
* */
public
Position
translate
(
float
dist
,
float
angle
)
{
this
.
x
+=
dist
*
Math
.
sin
(
angle
);
this
.
y
+=
dist
*
Math
.
cos
(
angle
);
return
this
;
}
public
boolean
equal2d
(
Position
other
)
{
return
getX
()
==
other
.
getX
()
&&
getY
()
==
other
.
getY
();
}
public
Position
translateWithDegrees
(
float
dist
,
float
angle
)
{
angle
=
(
float
)
Math
.
toRadians
(
angle
);
this
.
x
+=
dist
*
Math
.
sin
(
angle
);
this
.
y
+=
-
dist
*
Math
.
cos
(
angle
);
return
this
;
}
@Override
public
Position
clone
()
{
return
new
Position
(
x
,
y
,
z
);
}
@Override
public
String
toString
()
{
return
"("
+
this
.
getX
()
+
", "
+
this
.
getY
()
+
", "
+
this
.
getZ
()
+
")"
;
}
public
Vector
toProto
()
{
return
Vector
.
newBuilder
()
.
setX
(
this
.
getX
())
.
setY
(
this
.
getY
())
.
setZ
(
this
.
getZ
())
.
build
();
}
}
src/main/java/emu/grasscutter/utils/ProtoHelper.java
0 → 100644
View file @
7925d1cd
package
emu.grasscutter.utils
;
import
emu.grasscutter.game.props.PlayerProperty
;
import
emu.grasscutter.net.proto.PropValueOuterClass.PropValue
;
public
class
ProtoHelper
{
public
static
PropValue
newPropValue
(
PlayerProperty
key
,
int
value
)
{
return
PropValue
.
newBuilder
().
setType
(
key
.
getId
()).
setIval
(
value
).
setVal
(
value
).
build
();
}
}
src/main/java/emu/grasscutter/utils/Utils.java
0 → 100644
View file @
7925d1cd
package
emu.grasscutter.utils
;
import
java.io.BufferedInputStream
;
import
java.io.ByteArrayOutputStream
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.util.Random
;
import
emu.grasscutter.Grasscutter
;
import
io.netty.buffer.ByteBuf
;
import
io.netty.buffer.ByteBufUtil
;
import
io.netty.buffer.Unpooled
;
public
class
Utils
{
public
static
final
Random
random
=
new
Random
();
public
static
int
randomRange
(
int
min
,
int
max
)
{
return
random
.
nextInt
(
max
-
min
+
1
)
+
min
;
}
public
static
float
randomFloatRange
(
float
min
,
float
max
)
{
return
random
.
nextFloat
()
*
(
max
-
min
)
+
min
;
}
public
static
int
getCurrentSeconds
()
{
return
(
int
)
(
System
.
currentTimeMillis
()
/
1000.0
);
}
public
static
String
lowerCaseFirstChar
(
String
s
)
{
StringBuilder
sb
=
new
StringBuilder
(
s
);
sb
.
setCharAt
(
0
,
Character
.
toLowerCase
(
sb
.
charAt
(
0
)));
return
sb
.
toString
();
}
public
static
String
toString
(
InputStream
inputStream
)
throws
IOException
{
BufferedInputStream
bis
=
new
BufferedInputStream
(
inputStream
);
ByteArrayOutputStream
buf
=
new
ByteArrayOutputStream
();
for
(
int
result
=
bis
.
read
();
result
!=
-
1
;
result
=
bis
.
read
())
{
buf
.
write
((
byte
)
result
);
}
return
buf
.
toString
();
}
public
static
void
logByteArray
(
byte
[]
array
)
{
ByteBuf
b
=
Unpooled
.
wrappedBuffer
(
array
);
Grasscutter
.
getLogger
().
info
(
"\n"
+
ByteBufUtil
.
prettyHexDump
(
b
));
b
.
release
();
}
private
static
final
char
[]
HEX_ARRAY
=
"0123456789abcdef"
.
toCharArray
();
public
static
String
bytesToHex
(
byte
[]
bytes
)
{
char
[]
hexChars
=
new
char
[
bytes
.
length
*
2
];
for
(
int
j
=
0
;
j
<
bytes
.
length
;
j
++)
{
int
v
=
bytes
[
j
]
&
0xFF
;
hexChars
[
j
*
2
]
=
HEX_ARRAY
[
v
>>>
4
];
hexChars
[
j
*
2
+
1
]
=
HEX_ARRAY
[
v
&
0x0F
];
}
return
new
String
(
hexChars
);
}
public
static
String
bytesToHex
(
ByteBuf
buf
)
{
return
bytesToHex
(
byteBufToArray
(
buf
));
}
public
static
byte
[]
byteBufToArray
(
ByteBuf
buf
)
{
byte
[]
bytes
=
new
byte
[
buf
.
capacity
()];
buf
.
getBytes
(
0
,
bytes
);
return
bytes
;
}
public
static
int
abilityHash
(
String
str
)
{
int
v7
=
0
;
int
v8
=
0
;
while
(
v8
<
str
.
length
())
{
v7
=
str
.
charAt
(
v8
++)
+
131
*
v7
;
}
return
v7
;
}
}
src/main/java/emu/grasscutter/utils/WeightedList.java
0 → 100644
View file @
7925d1cd
package
emu.grasscutter.utils
;
import
java.util.NavigableMap
;
import
java.util.TreeMap
;
import
java.util.concurrent.ThreadLocalRandom
;
public
class
WeightedList
<
E
>
{
private
final
NavigableMap
<
Double
,
E
>
map
=
new
TreeMap
<
Double
,
E
>();
private
double
total
=
0
;
public
WeightedList
()
{
}
public
WeightedList
<
E
>
add
(
double
weight
,
E
result
)
{
if
(
weight
<=
0
)
return
this
;
total
+=
weight
;
map
.
put
(
total
,
result
);
return
this
;
}
public
E
next
()
{
double
value
=
ThreadLocalRandom
.
current
().
nextDouble
()
*
total
;
return
map
.
higherEntry
(
value
).
getValue
();
}
public
int
size
()
{
return
map
.
size
();
}
}
\ No newline at end of file
src/main/java/logback.xml
0 → 100644
View file @
7925d1cd
<Configuration>
<appender
name=
"STDOUT"
class=
"ch.qos.logback.core.ConsoleAppender"
>
<encoder>
<pattern>
[%d{HH:mm:ss}] [%level] %msg%n
</pattern>
</encoder>
</appender>
<logger
name=
"org.reflections"
level=
"OFF"
/>
<root
level=
"INFO"
>
<appender-ref
ref=
"STDOUT"
/>
</root>
</Configuration>
\ No newline at end of file
Prev
1
…
14
15
16
17
18
Next
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