Check-in [ecc28d369e]
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Fleet status indication
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:ecc28d369eeafceb39b91fbd049b9e86d47abfba
User & Date: linna 2016-10-30 08:03:29
Context
2016-10-30
08:03
Fleet status indication check-in: ba0b329442 user: linna tags: trunk
08:03
Fleet status indication check-in: ecc28d369e user: linna tags: trunk
2016-10-29
09:37
build shipType 3 check-in: 17134dfdfb user: linna tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to WarshipGirlsRSniffer/Protocol/Response/Index/GetInitConfigs.cs.

32
33
34
35
36
37
38
39


40

        [JsonIgnore] public DefaultTable<ShipCard> ShipCard => _shipCard ?? (_shipCard = shipCard.ToDefaultTable(x => x.cid));

        [JsonIgnore] private DefaultTable<ShipEquipment> _shipEquipments;
        [JsonIgnore] public DefaultTable<ShipEquipment> ShipEquipment => _shipEquipments ?? (_shipEquipments = shipEquipmnt.ToDefaultTable(x => x.cid));

        [JsonIgnore] private DefaultTable<ShipCampaignLevel> _shipCampaignLevel;
        [JsonIgnore] public DefaultTable<ShipCampaignLevel> ShipCampaignLevel => _shipCampaignLevel ?? (_shipCampaignLevel = shipCampaignLevel.ToDefaultTable(x => x.id));
    }


}








|
>
>
|
>
32
33
34
35
36
37
38
39
40
41
42
43
        [JsonIgnore] public DefaultTable<ShipCard> ShipCard => _shipCard ?? (_shipCard = shipCard.ToDefaultTable(x => x.cid));

        [JsonIgnore] private DefaultTable<ShipEquipment> _shipEquipments;
        [JsonIgnore] public DefaultTable<ShipEquipment> ShipEquipment => _shipEquipments ?? (_shipEquipments = shipEquipmnt.ToDefaultTable(x => x.cid));

        [JsonIgnore] private DefaultTable<ShipCampaignLevel> _shipCampaignLevel;
        [JsonIgnore] public DefaultTable<ShipCampaignLevel> ShipCampaignLevel => _shipCampaignLevel ?? (_shipCampaignLevel = shipCampaignLevel.ToDefaultTable(x => x.id));

        [JsonIgnore] private DefaultTable<PveExplore> _pveExplore;
        [JsonIgnore] public DefaultTable<PveExplore> PveExplore => _pveExplore ?? (_pveExplore = pveExplore.ToDefaultTable(x => x.id));
    }
}

Changes to WarshipGirlsRSniffer/View/Controls/ShipStatus.xaml.

17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
                        <Setter Property="Text" Value="正常" />
                        <Setter Property="Background" Value="LightGreen" />
                    </DataTrigger>
                    <DataTrigger Binding="{Binding Status}" Value="Repair">
                        <Setter Property="Text" Value="修理中" />
                        <Setter Property="Background" Value="LightBlue" />
                    </DataTrigger>
                    <DataTrigger Binding="{Binding Fleet.Status}" Value="Explore">
                        <Setter Property="Text" Value="远征中" />
                        <Setter Property="Background" Value="Yellow" />
                    </DataTrigger>
                    <DataTrigger Binding="{Binding Status}" Value="HeavilyDamaged">
                        <Setter Property="Text" Value="大破" />
                        <Setter Property="Background" Value="Red" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </TextBlock.Style>
    </TextBlock>
</UserControl>







|












17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
                        <Setter Property="Text" Value="正常" />
                        <Setter Property="Background" Value="LightGreen" />
                    </DataTrigger>
                    <DataTrigger Binding="{Binding Status}" Value="Repair">
                        <Setter Property="Text" Value="修理中" />
                        <Setter Property="Background" Value="LightBlue" />
                    </DataTrigger>
                    <DataTrigger Binding="{Binding Fleet.FleetStatus}" Value="Explore">
                        <Setter Property="Text" Value="远征中" />
                        <Setter Property="Background" Value="Yellow" />
                    </DataTrigger>
                    <DataTrigger Binding="{Binding Status}" Value="HeavilyDamaged">
                        <Setter Property="Text" Value="大破" />
                        <Setter Property="Background" Value="Red" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </TextBlock.Style>
    </TextBlock>
</UserControl>

Changes to WarshipGirlsRSniffer/View/Converter/BuildShipTypeToDescriptionConverter.cs.

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
            }

            switch((Vo.BuildShipType)value) {
                case Vo.BuildShipType.Unknown: return null;
                case Vo.BuildShipType.Cruiser: return "巡洋舰";
                case Vo.BuildShipType.Destroyer: return "驱逐舰";
                case Vo.BuildShipType.Carrier: return "航空母舰";
                default:return (byte)(Vo.BuildShipType)value + "类";
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}







|









13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
            }

            switch((Vo.BuildShipType)value) {
                case Vo.BuildShipType.Unknown: return null;
                case Vo.BuildShipType.Cruiser: return "巡洋舰";
                case Vo.BuildShipType.Destroyer: return "驱逐舰";
                case Vo.BuildShipType.Carrier: return "航空母舰";
                default:return $"#{(byte)(Vo.BuildShipType)value}";
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}

Changes to WarshipGirlsRSniffer/View/Docks.xaml.

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto" />
                        <ColumnDefinition Width="Auto" />
                    </Grid.ColumnDefinitions>

                    <TextBlock Grid.Column="0" Grid.Row="0" Grid.RowSpan="2" Text="{Binding Id}" VerticalAlignment="Center" Margin="10,0" FontSize="16" />
                    <TextBlock Grid.Column="1" Grid.Row="0" Text="{Binding Title}" Margin="0,4" FontSize="14" />
                    <TextBlock Grid.Column="1" Grid.Row="1" Text="{Binding RemainingTime, StringFormat={}{0:hh':'mm':'ss}}" Margin="0,4" />
                </Grid>
                <Border.Style>
                    <Style TargetType="Border">
                        <Setter Property="Visibility" Value="Visible" />
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding Locked}" Value="True">
                                <Setter Property="Visibility" Value="Collapsed" />







|







18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto" />
                        <ColumnDefinition Width="Auto" />
                    </Grid.ColumnDefinitions>

                    <TextBlock Grid.Column="0" Grid.Row="0" Grid.RowSpan="2" Text="{Binding Id}" VerticalAlignment="Center" Margin="10,0" FontSize="16" />
                    <TextBlock Grid.Column="1" Grid.Row="0" Text="{Binding Title}" Margin="0,4" FontSize="14" />
                    <TextBlock Grid.Column="1" Grid.Row="1" Text="{Binding RemainingTime, StringFormat={}{0:hh\\:mm\\:ss}}" Margin="0,4" />
                </Grid>
                <Border.Style>
                    <Style TargetType="Border">
                        <Setter Property="Visibility" Value="Visible" />
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding Locked}" Value="True">
                                <Setter Property="Visibility" Value="Collapsed" />

Changes to WarshipGirlsRSniffer/View/Fleets.xaml.

5
6
7
8
9
10
11
12




































13
14
15
16
17
18
19
20
















21
22
23
24



































25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:WarshipGirlsRSniffer.View"
             xmlns:control="clr-namespace:WarshipGirlsRSniffer.Controls"
             xmlns:vm="clr-namespace:WarshipGirlsRSniffer.Vm"
             xmlns:vc="clr-namespace:WarshipGirlsRSniffer.View.Controls"
             mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300">
    <StackPanel>
        <ListBox ItemsSource="{Binding}" Background="{x:Null}" BorderThickness="0" Margin="5,5,5,1" x:Name="selector">




































            <ListBox.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Horizontal" />
                </ItemsPanelTemplate>
            </ListBox.ItemsPanel>
            <ListBox.ItemTemplate>
                <DataTemplate DataType="vm:FleetVm">
                    <TextBlock Text="{Binding Title}" />
















                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>




































        <ItemsControl Margin="5,1,5,5" ItemsSource="{Binding SelectedItem.Ships, ElementName=selector}"
                      BorderThickness="1,1,0,0" BorderBrush="{DynamicResource {x:Static SystemColors.ScrollBarBrushKey}}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <UniformGrid Columns="2" Grid.IsSharedSizeScope="True" />
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate DataType="vm:ShipVm">
                    <Border BorderThickness="0,0,1,1" BorderBrush="{DynamicResource {x:Static SystemColors.ScrollBarBrushKey}}">
                        <Grid Margin="5">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto" MinWidth="72" SharedSizeGroup="ShipInfo" />
                                <ColumnDefinition Width="Auto" MinWidth="72" SharedSizeGroup="ShipLevel" />
                                <ColumnDefinition Width="*" />
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />







|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|









|







5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:WarshipGirlsRSniffer.View"
             xmlns:control="clr-namespace:WarshipGirlsRSniffer.Controls"
             xmlns:vm="clr-namespace:WarshipGirlsRSniffer.Vm"
             xmlns:vc="clr-namespace:WarshipGirlsRSniffer.View.Controls"
             mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300">
    <StackPanel>
        <ListBox ItemsSource="{Binding}" Background="{x:Null}" BorderThickness="0" Margin="3" x:Name="selector">
            <ListBox.Style>
                <Style TargetType="ListBox">
                    <Style.Triggers>
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="SelectedItem"
                                           Value="{x:Null}" />
                                <Condition Property="HasItems"
                                           Value="True" />
                            </MultiTrigger.Conditions>
                            <Setter Property="SelectedIndex"
                                    Value="0" />
                        </MultiTrigger>
                    </Style.Triggers>
                </Style>
            </ListBox.Style>
            <ListBox.ItemContainerStyle>
                <Style TargetType="ListBoxItem">
                    <Setter Property="SnapsToDevicePixels" Value="true"/>
                    <Setter Property="OverridesDefaultStyle" Value="true"/>
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="ListBoxItem">
                                <Border Name="Bd" Padding="4,2" SnapsToDevicePixels="True" BorderThickness="0,0,0,2">
                                    <ContentPresenter />
                                </Border>
                                <ControlTemplate.Triggers>
                                    <Trigger Property="IsSelected" Value="True">
                                        <Setter TargetName="Bd" Property="BorderBrush" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
                                    </Trigger>
                                </ControlTemplate.Triggers>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </ListBox.ItemContainerStyle>
            <ListBox.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Horizontal" />
                </ItemsPanelTemplate>
            </ListBox.ItemsPanel>
            <ListBox.ItemTemplate>
                <DataTemplate DataType="vm:FleetVm">
                    <TextBlock Text="{Binding Title}" Padding="4,2">
                        <TextBlock.Style>
                            <Style TargetType="TextBlock">
                                <Style.Triggers>
                                    <DataTrigger Binding="{Binding Status}" Value="Repair">
                                        <Setter Property="Background" Value="LightBlue" />
                                    </DataTrigger>
                                    <DataTrigger Binding="{Binding Status}" Value="Explore">
                                        <Setter Property="Background" Value="Yellow" />
                                    </DataTrigger>
                                    <DataTrigger Binding="{Binding Status}" Value="HeavilyDamaged">
                                        <Setter Property="Background" Value="Red" />
                                    </DataTrigger>
                                </Style.Triggers>
                            </Style>
                        </TextBlock.Style>
                    </TextBlock>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

        <TextBlock Padding="10,2" Margin="3,0" DataContext="{Binding SelectedItem, ElementName=selector}">
            <TextBlock.Style>
                <Style TargetType="TextBlock">
                    <Setter Property="Text" Value="没有数据" />
                    <Setter Property="Background" Value="LightGray" />

                    <Style.Triggers>
                        <DataTrigger Binding="{Binding Status}" Value="Normal">
                            <Setter Property="Text" Value="正常" />
                            <Setter Property="Background" Value="LightGreen" />
                        </DataTrigger>
                        <DataTrigger Binding="{Binding Status}" Value="Repair">
                            <Setter Property="Background" Value="LightBlue" />
                            <Setter Property="Text" Value="{Binding SlowestRepair.RemainingTime, StringFormat='修理中 - {0:hh\\:mm\\:ss}'}" />
                        </DataTrigger>
                        <DataTrigger Binding="{Binding Status}" Value="Explore">
                            <Setter Property="Background" Value="Yellow" />
                            <Setter Property="Text">
                                <Setter.Value>
                                    <MultiBinding StringFormat="远征中 - {0} - {1:hh\:mm\:ss}">
                                        <Binding Path="Explore.Title" />
                                        <Binding Path="Explore.RemainingTime" />
                                    </MultiBinding>
                                </Setter.Value>
                            </Setter>
                        </DataTrigger>
                        <DataTrigger Binding="{Binding Status}" Value="HeavilyDamaged">
                            <Setter Property="Text" Value="大破" />
                            <Setter Property="Background" Value="Red" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </TextBlock.Style>
        </TextBlock>

        <ItemsControl Margin="3" ItemsSource="{Binding SelectedItem.Ships, ElementName=selector}"
                      BorderThickness="1,1,0,0" BorderBrush="{DynamicResource {x:Static SystemColors.ScrollBarBrushKey}}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <UniformGrid Columns="2" Grid.IsSharedSizeScope="True" />
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate DataType="vm:ShipVm">
                    <Border BorderThickness="0,0,1,1" BorderBrush="{DynamicResource {x:Static SystemColors.ScrollBarBrushKey}}">
                        <Grid Margin="3">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto" MinWidth="72" SharedSizeGroup="ShipInfo" />
                                <ColumnDefinition Width="Auto" MinWidth="72" SharedSizeGroup="ShipLevel" />
                                <ColumnDefinition Width="*" />
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />

Changes to WarshipGirlsRSniffer/View/Fleets.xaml.cs.

7
8
9
10
11
12
13
14




15


    /// </summary>
    public partial class Fleets : UserControl
    {
        public Fleets()
        {
            InitializeComponent();
        }
    }




}









|
>
>
>
>
|
>
>
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
    /// </summary>
    public partial class Fleets : UserControl
    {
        public Fleets()
        {
            InitializeComponent();
        }

        private void selector_TargetUpdated(object sender, System.Windows.Data.DataTransferEventArgs e)
        {
            ListBox lb = sender as ListBox;
            if(lb?.HasItems == true) lb.SelectedIndex = 0;
        }
    }
}

Changes to WarshipGirlsRSniffer/Vm/BuildDockVm.cs.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

21
22
23
24
25
26
27
28
29
30
31

32
33
34
35
36




37
38
39
40
41
42
43

44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
using Linnaea.Extensions;
using System;
using System.Threading;
using WarshipGirlsRSniffer.Vo;

namespace WarshipGirlsRSniffer.Vm
{
    public class BuildDockVm : VmBase<BuildDockVm>
    {
        private static readonly View.Converter.BuildShipTypeToDescriptionConverter cvt = new View.Converter.BuildShipTypeToDescriptionConverter();

        private BuildDock vo;
        private readonly VmDock dock;
        private readonly Timer timer;

        public BuildDock Vo {
            get { return vo; }
            set { vo = value; RaiseMultiPropertyChanged(); UpdateTimer(this); }
        }


        private DateTimeOffset? _endTime;
        public DateTimeOffset? EndTime => _endTime;
        public byte Id => vo.id;
        public bool Locked => vo.locked != 0;
        public BuildShipType ShipType => (BuildShipType)vo.shipType;
        public string Title => cvt.Convert(ShipType, typeof(string), null, null) as string;
        public TimeSpan? RemainingTime {
            get
            {
                if(_endTime == null) {
                    return null;

                }
                var delta = _endTime.Value - DateTimeOffset.Now;
                return delta.Ticks < 0 ? TimeSpan.Zero : delta;
            }
        }





        public BuildDockVm(BuildDock vo, VmDock dock)
        {
            this.vo = vo;
            this.dock = dock;

            timer = new Timer(UpdateTimer, null, -1, -1);

            UpdateTimer(this);
        }

        private void UpdateTimer(object _)
        {
            RaisePropertyChanged(nameof(RemainingTime));
            if(_ != null) {
                _endTime = vo.endTime == 0 ? (DateTimeOffset?)null : DateTimeOffsetEx.FromUnixTimeSeconds(vo.endTime);
                if(RemainingTime.HasValue && RemainingTime != TimeSpan.Zero) {
                    timer.Change(1000, 1000);
                }
            }
            if(!RemainingTime.HasValue || RemainingTime == TimeSpan.Zero) {
                timer.Change(-1, -1);
            }
        }
    }
}
<
<
<




|





<



|
<
|
>
|
|
|
<
<
<
<
<
|
<
<
>
|
<
<
|
|
>
>
>
>





<
<
>


|
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<



1
2
3
4
5
6
7
8
9
10

11
12
13
14

15
16
17
18
19





20


21
22


23
24
25
26
27
28
29
30
31
32
33


34
35
36
37







38










using WarshipGirlsRSniffer.Vo;

namespace WarshipGirlsRSniffer.Vm
{
    public class BuildDockVm : VmTimerBase<BuildDockVm>
    {
        private static readonly View.Converter.BuildShipTypeToDescriptionConverter cvt = new View.Converter.BuildShipTypeToDescriptionConverter();

        private BuildDock vo;
        private readonly VmDock dock;


        public BuildDock Vo {
            get { return vo; }
            set

            {
                vo = value;
                endTime = vo.endTime;
                using(SuppressNotification())
                    UpdateTimer(this);








                RaiseMultiPropertyChanged();
            }


        }

        public override ushort Id => vo.id;
        public override bool Locked => vo.locked != 0;
        public BuildShipType ShipType => (BuildShipType)vo.shipType;
        public override string Title => cvt.Convert(ShipType, typeof(string), null, null) as string;

        public BuildDockVm(BuildDock vo, VmDock dock)
        {
            this.vo = vo;
            this.dock = dock;


            endTime = vo.endTime;
            UpdateTimer(this);
        }
    }







}







Changes to WarshipGirlsRSniffer/Vm/CampaignFleetVm.cs.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25


26


27
28
29
30
31
32





33



    {
        private int[] campaignFleet;
        private int campaignId;

        private readonly VmYard yard;

        public Protocol.Response.Campaign.GetFleet GetFleet {
            set { campaignFleet = value.campaignLevelFleet; campaignId = value.campaign_id; RaiseMultiPropertyChanged(); }
        }

        public Protocol.Response.Campaign.ChangeFleet ChangeFleet {
            set { campaignFleet = value.campaignLevelFleet; campaignId = value.campaign_id; RaiseMultiPropertyChanged(); }
        }

        public int Id => campaignId;
        public ShipStatus Status => ShipStatus.Normal;
        public ShipStatus FleetStatus => Ships.FirstOrDefault(x => x.Status != ShipStatus.Normal)?.Status ?? Status;
        public string Title => (Client.WGRSession.InitTxt.ShipCampaignLevel[campaignId].title ?? $"#{campaignId}") + $"-{Difficulty}";
        public int Difficulty => Client.WGRSession.InitTxt.ShipCampaignLevel[campaignId].difficulty;


        public ShipVm[] Ships => campaignFleet?.Select(x => yard.Ships[x]).ToArray();



        public CampaignFleetVm(VmYard yard)
        {
            this.yard = yard;
        }
    }





}










|



|



|
|


>
>
|
>
>





|
>
>
>
>
>
|
>
>
>
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
    {
        private int[] campaignFleet;
        private int campaignId;

        private readonly VmYard yard;

        public Protocol.Response.Campaign.GetFleet GetFleet {
            set { campaignFleet = value.campaignLevelFleet; campaignId = value.campaign_id; _ships = null; RaiseMultiPropertyChanged(); }
        }

        public Protocol.Response.Campaign.ChangeFleet ChangeFleet {
            set { campaignFleet = value.campaignLevelFleet; campaignId = value.campaign_id; _ships = null; RaiseMultiPropertyChanged(); }
        }

        public int Id => campaignId;
        public ShipStatus FleetStatus => ShipStatus.Normal;
        public ShipStatus Status => Ships.FirstOrDefault(x => x.Status != ShipStatus.Normal)?.Status ?? FleetStatus;
        public string Title => (Client.WGRSession.InitTxt.ShipCampaignLevel[campaignId].title ?? $"#{campaignId}") + $"-{Difficulty}";
        public int Difficulty => Client.WGRSession.InitTxt.ShipCampaignLevel[campaignId].difficulty;

        private ShipVm[] _ships;
        public ShipVm[] Ships => _ships ?? (_ships = campaignFleet?.Select(x => yard.Ships[x]).ToArray());

        public RepairDockVm SlowestRepair => yard.Session.Dock.RepairDock.Where(x => x.EndTime.HasValue && campaignFleet.Contains(x.Vo.shipId)).OrderByDescending(x => x.EndTime.Value).FirstOrDefault();

        public CampaignFleetVm(VmYard yard)
        {
            this.yard = yard;
        }

        internal void UpdateShip(int shipId)
        {
            if(campaignFleet.Contains(shipId)) {
                RaisePropertyChanged(nameof(Status));
                RaisePropertyChanged(nameof(SlowestRepair));
            }
        }
    }
}

Changes to WarshipGirlsRSniffer/Vm/EquipmentDockVm.cs.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

19
20
21
22
23
24
25
26
27
28
29

30
31
32
33
34





35
36
37
38
39
40
41

42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
using Linnaea.Extensions;
using System;
using System.Threading;
using WarshipGirlsRSniffer.Vo;

namespace WarshipGirlsRSniffer.Vm
{
    public class EquipmentDockVm : VmBase<RepairDockVm>
    {
        private EquipmentDock vo;
        private readonly VmDock dock;
        private readonly Timer timer;

        public EquipmentDock Vo {
            get { return vo; }
            set { vo = value; RaiseMultiPropertyChanged(); UpdateTimer(this); }
        }


        private DateTimeOffset? _endTime;
        public DateTimeOffset? EndTime => _endTime;
        public byte Id => vo.id;
        public bool Locked => vo.locked != 0;
        public string Title => Equipment.title;
        public ShipEquipment Equipment => Client.WGRSession.InitTxt.ShipEquipment[vo.equipmentCid];
        public TimeSpan? RemainingTime {
            get
            {
                if(_endTime == null) {
                    return null;

                }
                var delta = _endTime.Value - DateTimeOffset.Now;
                return delta.Ticks < 0 ? TimeSpan.Zero : delta;
            }
        }






        public EquipmentDockVm(EquipmentDock vo, VmDock dock)
        {
            this.vo = vo;
            this.dock = dock;

            timer = new Timer(UpdateTimer, null, -1, -1);

            UpdateTimer(this);
        }

        private void UpdateTimer(object _)
        {
            RaisePropertyChanged(nameof(RemainingTime));
            if(_ != null) {
                _endTime = vo.endTime == 0 ? (DateTimeOffset?)null : DateTimeOffsetEx.FromUnixTimeSeconds(vo.endTime);
                if(RemainingTime.HasValue && RemainingTime != TimeSpan.Zero) {
                    timer.Change(1000, 1000);
                }
            }
            if(!RemainingTime.HasValue || RemainingTime == TimeSpan.Zero) {
                timer.Change(-1, -1);
            }
        }
    }
}
<
<
<




|



<



|
<
|
>
|
|
|
<
<
<
<
<
|
<
<
>
|
<
<
|
|
>
>
>
>
>





<
<
>


|
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<



1
2
3
4
5
6
7
8

9
10
11
12

13
14
15
16
17





18


19
20


21
22
23
24
25
26
27
28
29
30
31
32


33
34
35
36







37










using WarshipGirlsRSniffer.Vo;

namespace WarshipGirlsRSniffer.Vm
{
    public class EquipmentDockVm : VmTimerBase<RepairDockVm>
    {
        private EquipmentDock vo;
        private readonly VmDock dock;


        public EquipmentDock Vo {
            get { return vo; }
            set

            {
                vo = value;
                endTime = vo.endTime;
                using(SuppressNotification())
                    UpdateTimer(this);








                RaiseMultiPropertyChanged();
            }


        }

        public override ushort Id => vo.id;
        public override bool Locked => vo.locked != 0;
        public override string Title => vo.equipmentCid == 0 ? null : Equipment.title ?? $"#{vo.equipmentCid}";

        public ShipEquipment Equipment => Client.WGRSession.InitTxt.ShipEquipment[vo.equipmentCid];

        public EquipmentDockVm(EquipmentDock vo, VmDock dock)
        {
            this.vo = vo;
            this.dock = dock;


            endTime = vo.endTime;
            UpdateTimer(this);
        }
    }







}







Changes to WarshipGirlsRSniffer/Vm/FleetVm.cs.

10
11
12
13
14
15
16
17
18
19
20
21
22
23



24
25
26
27
28
29




30



        public Fleet Vo {
            get { return vo; }
            set { vo = value; _ships = null;  RaiseMultiPropertyChanged(); }
        }

        public int Id => vo.id;
        public ShipStatus Status => (ShipStatus)vo.status;
        public ShipStatus FleetStatus => Status == ShipStatus.Normal ? (Ships?.FirstOrDefault(x => x?.Status != ShipStatus.Normal)?.Status ?? Status) : Status;
        public string Title => vo.title;

        private ShipVm[] _ships;
        public ShipVm[] Ships => _ships ?? (_ships = vo.ships?.Select(x => yard.Ships[x]).ToArray());




        public FleetVm(Fleet vo, VmYard yard)
        {
            this.vo = vo;
            this.yard = yard;
        }
    }




}









|
|





>
>
>





|
>
>
>
>
|
>
>
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

        public Fleet Vo {
            get { return vo; }
            set { vo = value; _ships = null;  RaiseMultiPropertyChanged(); }
        }

        public int Id => vo.id;
        public ShipStatus FleetStatus => (ShipStatus)vo.status;
        public ShipStatus Status => FleetStatus == ShipStatus.Normal ? (Ships?.FirstOrDefault(x => x?.Status != ShipStatus.Normal)?.Status ?? ShipStatus.Normal) : FleetStatus;
        public string Title => vo.title;

        private ShipVm[] _ships;
        public ShipVm[] Ships => _ships ?? (_ships = vo.ships?.Select(x => yard.Ships[x]).ToArray());

        public RepairDockVm SlowestRepair => yard.Session.Dock.RepairDock.Where(x => x.EndTime.HasValue && vo.ships.Contains(x.Vo.shipId)).OrderByDescending(x => x.EndTime.Value).FirstOrDefault();
        public PveExploreVm Explore => yard.Session.Pve.Explores.FirstOrDefault(x => ReferenceEquals(this, x.Fleet));

        public FleetVm(Fleet vo, VmYard yard)
        {
            this.vo = vo;
            this.yard = yard;
        }

        internal void UpdateShip()
        {
            RaisePropertyChanged(nameof(Status));
            RaisePropertyChanged(nameof(SlowestRepair));
        }
    }
}

Changes to WarshipGirlsRSniffer/Vm/RepairDockVm.cs.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

19
20
21
22
23
24
25
26
27
28
29

30
31
32
33
34





35
36
37
38
39
40
41

42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
using Linnaea.Extensions;
using System;
using System.Threading;
using WarshipGirlsRSniffer.Vo;

namespace WarshipGirlsRSniffer.Vm
{
    public class RepairDockVm : VmBase<RepairDockVm>
    {
        private RepairDock vo;
        private readonly VmDock dock;
        private readonly Timer timer;

        public RepairDock Vo {
            get { return vo; }
            set { vo = value; RaiseMultiPropertyChanged(); UpdateTimer(this); }
        }


        private DateTimeOffset? _endTime;
        public DateTimeOffset? EndTime => _endTime;
        public byte Id => vo.id;
        public bool Locked => vo.locked != 0;
        public string Title => Ship == null ? null : $"{Ship.Name} Lv.{Ship.Level}";
        public ShipVm Ship => dock.Session.Yard.Ships[vo.shipId];
        public TimeSpan? RemainingTime {
            get
            {
                if(_endTime == null) {
                    return null;

                }
                var delta = _endTime.Value - DateTimeOffset.Now;
                return delta.Ticks < 0 ? TimeSpan.Zero : delta;
            }
        }






        public RepairDockVm(RepairDock vo, VmDock dock)
        {
            this.vo = vo;
            this.dock = dock;

            timer = new Timer(UpdateTimer, null, -1, -1);

            UpdateTimer(this);
        }

        private void UpdateTimer(object _)
        {
            RaisePropertyChanged(nameof(RemainingTime));
            if(_ != null) {
                _endTime = vo.endTime == 0 ? (DateTimeOffset?)null : DateTimeOffsetEx.FromUnixTimeSeconds(vo.endTime);
                if(RemainingTime.HasValue && RemainingTime != TimeSpan.Zero) {
                    timer.Change(1000, 1000);
                }
            }
            if(!RemainingTime.HasValue || RemainingTime == TimeSpan.Zero) {
                timer.Change(-1, -1);
            }
        }
    }
}
<
<
<




|



<



|
<
|
>
|
|
|
<
<
<
<
<
|
<
<
>
|
<
<
|
|
>
>
>
>
>





<
<
>


|
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<



1
2
3
4
5
6
7
8

9
10
11
12

13
14
15
16
17





18


19
20


21
22
23
24
25
26
27
28
29
30
31
32


33
34
35
36







37










using WarshipGirlsRSniffer.Vo;

namespace WarshipGirlsRSniffer.Vm
{
    public class RepairDockVm : VmTimerBase<RepairDockVm>
    {
        private RepairDock vo;
        private readonly VmDock dock;


        public RepairDock Vo {
            get { return vo; }
            set

            {
                vo = value;
                endTime = vo.endTime;
                using(SuppressNotification())
                    UpdateTimer(this);








                RaiseMultiPropertyChanged();
            }


        }

        public override ushort Id => vo.id;
        public override bool Locked => vo.locked != 0;
        public override string Title => vo.shipId == 0 ? null : Ship == null ? $"#{vo.shipId}" : $"{Ship.Name} Lv.{Ship.Level}";

        public ShipVm Ship => dock.Session.Yard.Ships[vo.shipId];

        public RepairDockVm(RepairDock vo, VmDock dock)
        {
            this.vo = vo;
            this.dock = dock;


            endTime = vo.endTime;
            UpdateTimer(this);
        }
    }







}







Changes to WarshipGirlsRSniffer/Vm/ShipVm.cs.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
    public class ShipVm : VmBase<ShipVm>
    {
        private UserShip vo;
        private readonly VmYard yard;

        public UserShip Vo {
            get { return vo; }
            set { vo = value; _equipments = null; RaiseMultiPropertyChanged(); }
        }

        public int Id => vo.id;
        public int Exp => vo.exp;
        public int Cid => vo.shipCid;
        public int Level => vo.level;
        public int NextExp => vo.nextExp;







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
    public class ShipVm : VmBase<ShipVm>
    {
        private UserShip vo;
        private readonly VmYard yard;

        public UserShip Vo {
            get { return vo; }
            set { vo = value; _equipments = null; RaiseMultiPropertyChanged(); Fleet?.UpdateShip(); }
        }

        public int Id => vo.id;
        public int Exp => vo.exp;
        public int Cid => vo.shipCid;
        public int Level => vo.level;
        public int NextExp => vo.nextExp;

Changes to WarshipGirlsRSniffer/Vm/VmSession.cs.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

18
19
20
21
22
23
24

25
26
27
using System.Reactive.Disposables;

namespace WarshipGirlsRSniffer.Vm
{
    public class VmSession : VmBase<VmSession>
    {
        private CompositeDisposable _disposable = new CompositeDisposable();

        public Client.WGRSession Session { get; }

        public string Host => Session.Id.Host;

        public int Uid => Session.Id.Uid;

        public VmYard Yard { get; }
        public VmUser User { get; }
        public VmDock Dock { get; }


        public VmSession(Client.WGRSession sess)
        {
            Session = sess;
            User = new VmUser(this);
            Yard = new VmYard(this);
            Dock = new VmDock(this);

        }
    }
}
<
<




<
<









>







>





1
2
3
4


5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25


namespace WarshipGirlsRSniffer.Vm
{
    public class VmSession : VmBase<VmSession>
    {


        public Client.WGRSession Session { get; }

        public string Host => Session.Id.Host;

        public int Uid => Session.Id.Uid;

        public VmYard Yard { get; }
        public VmUser User { get; }
        public VmDock Dock { get; }
        public VmPve Pve { get; }

        public VmSession(Client.WGRSession sess)
        {
            Session = sess;
            User = new VmUser(this);
            Yard = new VmYard(this);
            Dock = new VmDock(this);
            Pve = new VmPve(this);
        }
    }
}

Changes to WarshipGirlsRSniffer/Vm/VmYard.cs.

9
10
11
12
13
14
15

16
17
18

19
20
21
22
23
24
25
..
91
92
93
94
95
96
97


98
99
100
101
102
103
104
    {
        private CompositeDisposable _disposable = new CompositeDisposable();

        public DefaultTable<ShipVm> Ships { get; } = new DefaultTable<ShipVm>();
        public DefaultTable<EquipmentVm> Equipments { get; } = new DefaultTable<EquipmentVm>();
        public DefaultTable<FleetVm> Fleets { get; } = new DefaultTable<FleetVm>();
        public DefaultTable<CampaignFleetVm> CampaignFleets { get; } = new DefaultTable<CampaignFleetVm>();


        public VmYard(VmSession _)
        {

            _disposable.Add(_.Session.Api_Api_InitGame.Subscribe(OnGameInit));

            _disposable.Add(_.Session.Api_Boat_ChangeEquipment.Subscribe(p => UpdateShip(p.Item2.shipVO)));
            _disposable.Add(_.Session.Api_Boat_RemoveEquipment.Subscribe(p => UpdateShip(p.Item2.shipVO)));
            _disposable.Add(_.Session.Api_Boat_Repair.Subscribe(p => UpdateShip(p.Item2.shipVO)));
            _disposable.Add(_.Session.Api_Boat_RepairComplete.Subscribe(p => { if(p.Item2.status != 0) UpdateShip(p.Item2.shipVO); }));
            _disposable.Add(_.Session.Api_Boat_Strengthen.Subscribe(p => UpdateShip(p.Item2.shipVO)));
................................................................................
                if(Equipments.ContainsKey(cid)) return;

                App.BeginDispatcherInvoke(() => {
                    if(Equipments.ContainsKey(cid)) return;
                    Equipments[cid] = new EquipmentVm(new Vo.Equipment() { equipmentCid = cid, uid = vo.uid }, this);
                });
            });


        }

        private void UpdateFleet(Vo.Fleet vo)
        {
            var fleet = Fleets[vo.id];
            if(fleet != null) {
                fleet.Vo = vo;







>



>







 







>
>







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
..
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
    {
        private CompositeDisposable _disposable = new CompositeDisposable();

        public DefaultTable<ShipVm> Ships { get; } = new DefaultTable<ShipVm>();
        public DefaultTable<EquipmentVm> Equipments { get; } = new DefaultTable<EquipmentVm>();
        public DefaultTable<FleetVm> Fleets { get; } = new DefaultTable<FleetVm>();
        public DefaultTable<CampaignFleetVm> CampaignFleets { get; } = new DefaultTable<CampaignFleetVm>();
        public readonly VmSession Session;

        public VmYard(VmSession _)
        {
            Session = _;
            _disposable.Add(_.Session.Api_Api_InitGame.Subscribe(OnGameInit));

            _disposable.Add(_.Session.Api_Boat_ChangeEquipment.Subscribe(p => UpdateShip(p.Item2.shipVO)));
            _disposable.Add(_.Session.Api_Boat_RemoveEquipment.Subscribe(p => UpdateShip(p.Item2.shipVO)));
            _disposable.Add(_.Session.Api_Boat_Repair.Subscribe(p => UpdateShip(p.Item2.shipVO)));
            _disposable.Add(_.Session.Api_Boat_RepairComplete.Subscribe(p => { if(p.Item2.status != 0) UpdateShip(p.Item2.shipVO); }));
            _disposable.Add(_.Session.Api_Boat_Strengthen.Subscribe(p => UpdateShip(p.Item2.shipVO)));
................................................................................
                if(Equipments.ContainsKey(cid)) return;

                App.BeginDispatcherInvoke(() => {
                    if(Equipments.ContainsKey(cid)) return;
                    Equipments[cid] = new EquipmentVm(new Vo.Equipment() { equipmentCid = cid, uid = vo.uid }, this);
                });
            });

            CampaignFleets.ForEach(x => x.UpdateShip(vo.id));
        }

        private void UpdateFleet(Vo.Fleet vo)
        {
            var fleet = Fleets[vo.id];
            if(fleet != null) {
                fleet.Vo = vo;

Changes to WarshipGirlsRSniffer/Vo/PveExploreVo.cs.

73
74
75
76
77
78
79


80
81
82
83
84
85
86
87
88
    [JsonObject] public struct UserPveLevel
    {
        public int id, uid, status, hp, support_level, support_status, support_oil, support_ammo, support_aluminium, pveLevelId;
    }

    [JsonObject] public struct PveExploreLevel
    {


        public int exploreId, fleetId, startTime, endTime;
    }

    [JsonObject] public struct UserPveExplore
    {
        public PveExploreLevel[] levels;
        public int[] chapters;
    }
}







>
>
|








73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
    [JsonObject] public struct UserPveLevel
    {
        public int id, uid, status, hp, support_level, support_status, support_oil, support_ammo, support_aluminium, pveLevelId;
    }

    [JsonObject] public struct PveExploreLevel
    {
        public ushort exploreId;
        public byte fleetId;
        public int startTime, endTime;
    }

    [JsonObject] public struct UserPveExplore
    {
        public PveExploreLevel[] levels;
        public int[] chapters;
    }
}

Changes to WarshipGirlsRSniffer/WarshipGirlsRSniffer.csproj.

222
223
224
225
226
227
228

229
230


231
232
233
234
235
236
237
      <DependentUpon>Fleets.xaml</DependentUpon>
    </Compile>
    <Compile Include="View\Ships.xaml.cs">
      <DependentUpon>Ships.xaml</DependentUpon>
    </Compile>
    <Compile Include="Vm\EquipmentDockVm.cs" />
    <Compile Include="Vm\CampaignFleetVm.cs" />

    <Compile Include="Vm\VmDock.cs" />
    <Compile Include="Vm\FleetVm.cs" />


    <Compile Include="Vm\VmUser.cs" />
    <Compile Include="Vo\CampaignVo.cs" />
    <Compile Include="Vo\Constants.cs" />
    <Compile Include="Vo\DockVo.cs" />
    <Compile Include="Vo\EnemyVo.cs" />
    <Compile Include="Vo\FriendVo.cs" />
    <Compile Include="Vo\MarketingDataVo.cs" />







>


>
>







222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
      <DependentUpon>Fleets.xaml</DependentUpon>
    </Compile>
    <Compile Include="View\Ships.xaml.cs">
      <DependentUpon>Ships.xaml</DependentUpon>
    </Compile>
    <Compile Include="Vm\EquipmentDockVm.cs" />
    <Compile Include="Vm\CampaignFleetVm.cs" />
    <Compile Include="Vm\PveExploreVm.cs" />
    <Compile Include="Vm\VmDock.cs" />
    <Compile Include="Vm\FleetVm.cs" />
    <Compile Include="Vm\VmPve.cs" />
    <Compile Include="Vm\VmTimerBase.cs" />
    <Compile Include="Vm\VmUser.cs" />
    <Compile Include="Vo\CampaignVo.cs" />
    <Compile Include="Vo\Constants.cs" />
    <Compile Include="Vo\DockVo.cs" />
    <Compile Include="Vo\EnemyVo.cs" />
    <Compile Include="Vo\FriendVo.cs" />
    <Compile Include="Vo\MarketingDataVo.cs" />