# this is to allow the feed to "warm up" with duplicates
# so that the "big rush" doesn't happen.
-our $minspottime = 30*60; # the time between respots of a callsign - if a call is
+our $respottime = 3*60; # the time between respots of a callsign - if a call is
# still being spotted (on the same freq) and it has been
# spotted before, it's spotted again after this time
- # until the next minspottime has passed.
+ # until the next respottime has passed.
+
our $beacontime = 5*60; # same as minspottime, but for beacons (and shorter)
# simply be that it is not in standard spot coverage. (ask G4PIQ
# about this).
+our $cachetime = 60*60; # The length of time spot data is cached
+
our $filterdef = $Spot::filterdef; # we use the same filter as the Spot system. Can't think why :-).
my $spots; # the GLOBAL spot cache
+my $qrg; # the GlOBAL (ephemeral) qrg cache (generated on re-read of cache)
+
my %runtime; # how long each channel has been running
my $noinrush = 0; # override the inrushpreventor if set
our $maxdeviants = 5; # the number of deviant QRGs to record for skimmer records
+our %seeme; # the list of users that want to see themselves
+
+
sub init
{
$json = DXJSON->new;
$self->{norawhour} = 0;
$self->{sort} = 'N';
$self->{lasttime} = $main::systime;
- $self->{minspottime} = $minspottime;
+ $self->{respottime} = $respottime;
$self->{beacontime} = $beacontime;
$self->{showstats} = 0;
$self->{pingint} = 0;
my $name = $user->{name};
# log it
- my $host = $self->{conn}->peerhost;
- $host ||= "unknown";
- $self->{hostname} = $host;
+ unless ($self->{hostname}) {
+ $self->{hostname} = $self->{conn}->peerhost || 'unknown';
+ }
$self->{name} = $name ? $name : $call;
$self->state('prompt'); # a bit of room for further expansion, passwords etc
$self->{width} = 80 unless $self->{width} && $self->{width} > 80;
$self->{consort} = $line; # save the connection type
- LogDbg('DXCommand', "$call connected from $self->{hostname}");
+ LogDbg('err', "$call connected from $self->{hostname}");
# set some necessary flags on the user if they are connecting
$self->{registered} = 1;
return;
}
+ # is it 'baddx'
+ if ($DXProt::baddx->in($call)) {
+ dbg("RBN: Bad DX spot '$call', ignored");
+ dbg($line) if isdbg('nologchan');
+ return;
+ }
+
+
# remove all extraneous crap from the origin - just leave the base callsign
my $norigin = basecall($origin);
unless ($norigin) {
my $nqrg = nearest(1, $qrg * 10); # normalised to nearest Khz
my $sp = "$call|$nqrg"; # hopefully the skimmers will be calibrated at least this well!
+ # deal with the unix time
+ my ($hh,$mm) = $t =~ /(\d\d)(\d\d)Z$/;
+ my $utz = $hh*3600 + $mm*60 + $main::systime_daystart; # possible issue with late spot from previous day
+ $utz -= 86400 if $utz > $now+3600; # too far ahead, drag it back one day
+
+ #
+ # But before we do anything, if this call is in the seeme hash then just send the spot to them
+ #
+ if (exists $seeme{$call} && (my $ref = $seeme{$call})) {
+ foreach my $rcall ( @$ref) {
+ my $uchan = DXChannel::get($rcall);
+ if ($uchan) {
+ if ($uchan->is_user) {
+ if (isdbg('seeme')) {
+ dbg("seeme: $line");
+ dbg( qq{seemme:decode or:$origin qr:$qrg ca:$call mo:$mode s:$s m:$m sp:$spd u:$u sort:$sort t:$t tx:$tx qra:$qra});
+ }
+ my @s = Spot::prepare($qrg, $call, $utz, sprintf("%-3s %2ddB **SEEME**", $mode, $s), $origin.'-#');
+ my $buf = $uchan->format_dx_spot(@s);
+ dbg("seeme: result '$buf'") if isdbg('seeme');
+ $uchan->local_send('S', $buf);
+ } else {
+ LogDbg('err',"RBN Someone is playing silly persons $rcall is not a user and cannot do 'seeme', ignored and reset");
+ del_seeme($rcall);
+ }
+ }
+ }
+ }
+
# find it?
my $cand = $spots->{$sp};
unless ($cand) {
my $respot = 0;
if ($cand && ref $cand) {
if (@$cand <= CData) {
- if ($self->{minspottime} > 0 && $now - $cand->[CTime] < $self->{minspottime}) {
+ if ($self->{respottime} > 0 && $now - $cand->[CTime] < $self->{respottime}) {
dbg("RBN: key: '$sp' call: $call qrg: $qrg DUPE \@ ". atime(int $cand->[CTime])) if $dbgrbn && isdbg('rbn');
return;
}
return unless $noinrush || $self->{inrushpreventor} < $main::systime;
# build up a new record and store it in the buildup
- # deal with the unix time
- my ($hh,$mm) = $t =~ /(\d\d)(\d\d)Z$/;
- my $utz = $hh*3600 + $mm*60 + $main::systime_daystart; # possible issue with late spot from previous day
- $utz -= 86400 if $utz > $now+3600; # too far ahead, drag it back one day
-
# create record and add into the buildup
my $r = [$origin, nearest(.1, $qrg), $call, $mode, $s, $t, $utz, $respot, $u];
my @s = Spot::prepare($r->[RQrg], $r->[RCall], $r->[RUtz], '', $r->[ROrigin]);
my $self = shift;
my $quality = shift;
my $cand = shift;
-
+
++$self->{norbn};
++$self->{norbn10};
++$self->{norbnhour};
my $quality = shift;
my $cand = shift;
my $call = $dxchan->{call};
- my $seeme = $dxchan->user->rbnseeme();
my $strength = 100; # because it could if we talk about FTx
my $saver;
my %zone;
++$zone{$s->[SZone]}; # save the spotter's zone
- # if the 'see me' flag is set, then show all the spots without further adornment (see set/rbnseeme for more info)
- if ($seeme) {
- send_final($dxchan, $s);
- next;
- }
-
# save the lowest strength one
if ($r->[RStrength] < $strength) {
$strength = $r->[RStrength];
unless ($user->qra && is_qra($user->qra)) {
$user->qra($qra);
dbg("RBN: update qra on $saver->[SCall] to $qra");
- $user->put;
}
+ # update lastseen if nothing else
+ $user->put;
}
}
}
$buf = $dxchan->format_dx_spot(@$saver);
$saver->[SOrigin] = $call;
}
- $dxchan->local_send('N', $buf);
+ $dxchan->local_send('R', $buf);
}
# per second
next unless $dxchan->is_rbn;
dbg "RBN:STATS minute $dxchan->{call} raw: $dxchan->{noraw} retrieved spots: $dxchan->{norbn} delivered: $dxchan->{nospot} after filtering to users: " . scalar keys %{$dxchan->{nousers}} if isdbg('rbnstats');
if ($dxchan->{noraw} == 0 && $dxchan->{lasttime} > 60) {
- LogDbg('RBN', "RBN: no input from $dxchan->{call}, disconnecting");
+ LogDbg('err', "RBN: no input from $dxchan->{call}, disconnecting");
$dxchan->disconnect;
}
$dxchan->{noraw} = $dxchan->{norbn} = $dxchan->{nospot} = 0; $dxchan->{nousers} = {};
next if $k =~ /^O\|/;
next if $k =~ /^SKIM\|/;
- if ($main::systime - $cand->[CTime] > $minspottime*2) {
+ if ($main::systime - $cand->[CTime] > $cachetime) {
delete $spots->{$k};
++$removed;
}
sub write_cache
{
+ return unless $json;
+
my $ta = [ gettimeofday ];
+
$json->indent(1)->canonical(1) if isdbg 'rbncache';
my $s = eval {$json->encode($spots)};
if ($s) {
return undef;
}
+sub add_seeme
+{
+ my $call = shift;
+ my $base = basecall($call);
+ my $ref = $seeme{$base} || [];
+ push @$ref, $call unless grep $_ eq $call, @$ref;
+ $seeme{$base} = $ref;
+}
+
+sub del_seeme
+{
+ my $call = shift;
+ my $base = basecall($call);
+ my $ref = $seeme{$base};
+ return unless $ref && @$ref;
+
+ @$ref = grep {$_ ne $call} @$ref;
+ if (@$ref) {
+ $seeme{$base} = $ref;
+ } else {
+ delete $seeme{basecall($call)};
+ }
+}
1;