ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/ext/highscore.ext
(Generate patch)

Comparing deliantra/server/ext/highscore.ext (file contents):
Revision 1.7 by root, Sun May 9 22:51:13 2010 UTC vs.
Revision 1.8 by root, Fri Feb 3 02:04:11 2012 UTC

3use Fcntl (); 3use Fcntl ();
4use Coro::AIO; 4use Coro::AIO;
5 5
6our $HIGHSCORE_ENTRIES = $cf::CFG{highscore_entries} || 1000; 6our $HIGHSCORE_ENTRIES = $cf::CFG{highscore_entries} || 1000;
7 7
8our $HIGHSCORE;
9
8# [name, title, exp, killer, where, hp, sp, gp, uuid] 10# [name, title, exp, killer, where, hp, sp, gp, uuid]
9 11
10sub load_hiscore() { 12sub load_highscore() {
11# if (0 <= aio_load "$cf::LOCALDIR/hiscore.json", my $json) { 13# if (0 <= aio_load "$cf::LOCALDIR/hiscore.json", my $json) {
12# return JSON::XS::decode_json $json; 14# return JSON::XS::decode_json $json;
13# } 15# }
14 16
15 # try to convert old highscore file 17 # try to convert old highscore file
19 } 21 }
20 22
21 return []; 23 return [];
22} 24}
23 25
24sub save_hiscore($) { 26sub reload {
25 my ($hiscore) = @_; 27 my $lock = cf::lock_acquire "highscore";
26 28
27 my $fh = aio_open "$cf::LOCALDIR/highscore~", Fcntl::O_WRONLY | Fcntl::O_CREAT | Fcntl::O_TRUNC, 0644 29 cf::async_ext {
28 or return; 30 $lock;
29 31
30 $hiscore = join "", map "$_\n", map +(join ":", @$_), @$hiscore; 32 $HIGHSCORE = load_highscore;
33 };
34}
31 35
32 length $hiscore == aio_write $fh, 0, (length $hiscore), $hiscore, 0 36cf::post_init {
33 or return; 37 reload;
38};
34 39
35 # always fsync - this file is important 40sub save_highscore() {
36 aio_fsync $fh 41 my $highscore = join "", map "$_\n", map +(join ":", @$_), @$HIGHSCORE;
37 and return;
38 42
39 close $fh 43 cf::replace_file "$cf::LOCALDIR/highscore", $highscore, 1;
40 or return;
41
42 aio_rename "$cf::LOCALDIR/highscore~", "$cf::LOCALDIR/highscore"
43 and return;
44
45 aio_pathsync "$cf::LOCALDIR";
46
47 cf::trace "saved highscore file.\n"; 44 cf::trace "saved highscore file.\n";
48 45
49 1 46 1
50} 47}
51 48
81 $ob->stats->maxgrace, 78 $ob->stats->maxgrace,
82 $ob->uuid, 79 $ob->uuid,
83 int AE::now, 80 int AE::now,
84 ]; 81 ];
85 82
86 my $guard = cf::lock_acquire "highscore:check"; 83 my $guard = cf::lock_acquire "highscore";
87
88 # load hiscore, patch, save hiscore
89 my $hiscore = load_hiscore;
90 84
91 cf::get_slot 0.01, 0, "highscore check"; 85 cf::get_slot 0.01, 0, "highscore check";
92 86
93 my ($pre, $ins, $save); 87 my ($pre, $ins, $save);
94 88
95 pop @$hiscore while @$hiscore > $HIGHSCORE_ENTRIES; 89 pop @$HIGHSCORE while @$HIGHSCORE > $HIGHSCORE_ENTRIES;
96 90
97 # find previous entry, and new position 91 # find previous entry, and new position
98 92
99 for (0 .. $#$hiscore) { 93 for (0 .. $#$HIGHSCORE) {
100 $pre //= $_ if $hiscore->[$_][0] eq $score->[0]; 94 $pre //= $_ if $HIGHSCORE->[$_][0] eq $score->[0];
101 $ins //= $_ if $hiscore->[$_][2] < $score->[2]; 95 $ins //= $_ if $HIGHSCORE->[$_][2] < $score->[2];
102 } 96 }
103 cf::cede_to_tick; # we need an "interruptible" block... 97 cf::cede_to_tick; # we need an "interruptible" block...
104 98
105 my $msg; 99 my $msg;
106 100
107 if (defined $pre) { 101 if (defined $pre) {
108 # we are already in the list 102 # we are already in the list
109 if ($hiscore->[$pre][2] < $score->[2]) { 103 if ($HIGHSCORE->[$pre][2] < $score->[2]) {
110 $msg = "T<You beat your last score!>\n\n" 104 $msg = "T<You beat your last score!>\n\n"
111 . $SEP 105 . $SEP
112 . $HEADER 106 . $HEADER
113 . $SEP 107 . $SEP
114 . (fmt $ins, $score) 108 . (fmt $ins, $score)
115 . (fmt $pre, $hiscore->[$pre]) 109 . (fmt $pre, $HIGHSCORE->[$pre])
116 . $SEP; 110 . $SEP;
117 111
118 splice @$hiscore, $pre, 1; 112 splice @$HIGHSCORE, $pre, 1;
119 splice @$hiscore, $ins, 0, $score; 113 splice @$HIGHSCORE, $ins, 0, $score;
120 $save = 1; 114 $save = 1;
121 } else { 115 } else {
122 $msg = "T<You did not beat your last score.>\n\n" 116 $msg = "T<You did not beat your last score.>\n\n"
123 . $SEP 117 . $SEP
124 . $HEADER 118 . $HEADER
125 . $SEP 119 . $SEP
126 . (fmt $pre , $hiscore->[$pre]) 120 . (fmt $pre , $HIGHSCORE->[$pre])
127 . (fmt undef, $score) 121 . (fmt undef, $score)
128 . $SEP; 122 . $SEP;
129 } 123 }
130 } elsif (defined $ins or @$hiscore < $HIGHSCORE_ENTRIES) { 124 } elsif (defined $ins or @$HIGHSCORE < $HIGHSCORE_ENTRIES) {
131 $ins //= @$hiscore; 125 $ins //= @$HIGHSCORE;
132 126
133 $msg = "T<You entered the highscore list!>\n\n" 127 $msg = "T<You entered the highscore list!>\n\n"
134 . $SEP 128 . $SEP
135 . $HEADER 129 . $HEADER
136 . $SEP 130 . $SEP
137 . (fmt $ins, $score) 131 . (fmt $ins, $score)
138 . $SEP; 132 . $SEP;
139 133
140 splice @$hiscore, $ins, 0, $score; 134 splice @$HIGHSCORE, $ins, 0, $score;
141 $save = 1; 135 $save = 1;
142 } else { 136 } else {
143 $msg = "T<You did not enter the highscore list.>\n\n" 137 $msg = "T<You did not enter the highscore list.>\n\n"
144 . $SEP 138 . $SEP
145 . $HEADER 139 . $HEADER
146 . $SEP 140 . $SEP
147 . (fmt -1 + (scalar @$hiscore), $hiscore->[-1]) 141 . (fmt -1 + (scalar @$HIGHSCORE), $HIGHSCORE->[-1])
148 . (fmt undef, $score) 142 . (fmt undef, $score)
149 . $SEP; 143 . $SEP;
150 } 144 }
151 145
152 cf::info $msg;#d# remove once working stable 146 cf::info $msg;#d# remove once working stable
153 147
154 $ob->send_msg ($SCORE_CHANNEL => $msg, cf::NDI_CLEAR); 148 $ob->send_msg ($SCORE_CHANNEL => $msg, cf::NDI_CLEAR);
155 149
156 if ($save) { 150 if ($save) {
157 save_hiscore $hiscore 151 save_highscore
158 or die "unable to write highscore file: $!"; 152 or die "unable to write highscore file: $!";
159 } 153 }
160} 154}
161 155

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines